summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore10
-rw-r--r--.gitlab-ci.yml33
-rw-r--r--Dockerfile8
-rw-r--r--archetypes/default.md6
-rw-r--r--assets/theme/main.scss313
-rwxr-xr-xbin/make-docker16
-rwxr-xr-xbin/make-feeds71
-rwxr-xr-xbin/make-mimetypes36
-rwxr-xr-xbin/publish75
-rw-r--r--config.toml13
-rw-r--r--content/_index.md94
-rw-r--r--content/http-404.md6
-rw-r--r--content/posts/2016/2016-10-01-on-pastebin.md (renamed from src/_posts/2016-10-01-on-pastebin.md)12
-rw-r--r--content/posts/2016/2016-10-01-on-systemd.md (renamed from src/_posts/2016-10-01-on-systemd.md)12
-rw-r--r--content/posts/2016/2016-10-25-setup-a-vpn-with-cjdns.md (renamed from src/_posts/2016-10-25-setup-a-vpn-with-cjdns.md)67
-rw-r--r--content/posts/2016/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md (renamed from src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md)49
-rw-r--r--content/posts/2016/2016-10-31-freebsd-mailserver-part-1-preparations.md (renamed from src/_posts/2016-10-31-freebsd-mailserver-part-1-preparations.md)46
-rw-r--r--content/posts/2016/2016-10-31-freebsd-mailserver-part-2-mailing-with-postfix.md (renamed from src/_posts/2016-10-31-freebsd-mailserver-part-2-mailing-with-postfix.md)13
-rw-r--r--content/posts/2016/2016-10-31-freebsd-mailserver-part-3-dovecot-imap-sasl.md (renamed from src/_posts/2016-10-31-freebsd-mailserver-part-3-dovecot-imap-sasl.md)63
-rw-r--r--content/posts/2016/2016-10-31-freebsd-mailserver-part-4-message-authentication.md (renamed from src/_posts/2016-10-31-freebsd-mailserver-part-4-message-authentication.md)38
-rw-r--r--content/posts/2016/2016-10-31-freebsd-mailserver-part-5-filtering-mail.md (renamed from src/_posts/2016-10-31-freebsd-mailserver-part-5-filtering-mail.md)39
-rw-r--r--content/posts/2016/2016-11-24-freebsd-mailserver-calendars-and-contacts.md (renamed from src/_posts/2016-11-24-freebsd-mailserver-calendars-and-contacts.md)52
-rw-r--r--content/posts/2016/_index.md3
-rw-r--r--content/posts/2017/2017-09-14-how-to-git.md (renamed from src/_posts/2017-09-14-how-to-git.md)22
-rw-r--r--content/posts/2017/2017-09-28-perl6-creating-a-background-service.md (renamed from src/_posts/2017-09-28-perl6-creating-a-background-service.adoc)96
-rw-r--r--content/posts/2017/2017-11-01-hacktoberfest-2017.md (renamed from src/_posts/2017-11-01-hacktoberfest-2017.adoc)98
-rw-r--r--content/posts/2017/2017-11-16-perl6-setting-up-a-raspberry-perl.md (renamed from src/_posts/2017-11-16-perl6-setting-up-a-raspberry-perl.adoc)126
-rw-r--r--content/posts/2017/2017-12-17-on-cloudflare.md (renamed from src/_posts/2017-12-17-on-cloudflare.adoc)67
-rw-r--r--content/posts/2017/2017-12-21-funding-yourself-as-free-software-developer.md (renamed from src/_posts/2017-12-21-funding-yourself-as-free-software-developer.adoc)112
-rw-r--r--content/posts/2017/_index.md3
-rw-r--r--content/posts/2018/2018-02-05-why-perl6.md (renamed from src/_posts/2018-02-05-why-perl6.adoc)145
-rw-r--r--content/posts/2018/2018-03-20-perl6-introduction-to-application-programming.md (renamed from src/_posts/2018-03-20-perl6-introduction-to-application-programming.adoc)352
-rw-r--r--content/posts/2018/2018-05-07-sparrowdo-getting-started.md (renamed from src/_posts/2018-05-07-sparrowdo-getting-started.adoc)144
-rw-r--r--content/posts/2018/2018-08-15-the-perl-conference-in-glasgow.md (renamed from src/_posts/2018-08-15-the-perl-conference-in-glasgow.adoc)160
-rw-r--r--content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md (renamed from src/_posts/2018-09-04-setting-up-pgp-with-a-yubikey.adoc)186
-rw-r--r--content/posts/2018/2018-09-13-hackerrank-solutions-python3-and-perl6-part-1.md (renamed from src/_posts/2018-09-13-hackerrank-solutions-python3-and-perl6-part-1.adoc)206
-rw-r--r--content/posts/2018/_index.md3
-rw-r--r--content/posts/2019/2019-02-03-how-to-sign-pgp-keys.md (renamed from src/_posts/2019-02-03-how-to-sign-pgp-keys.html)52
-rw-r--r--content/posts/2019/2019-04-11-perl6-nightly-docker-images.md (renamed from src/_posts/2019-04-11-perl6-nightly-docker-images.html)42
-rw-r--r--content/posts/2019/2019-07-22-the-powerful-tooling-of-gentoo.md (renamed from src/_posts/2019-07-22-the-powerful-tooling-of-gentoo.html)24
-rw-r--r--content/posts/2019/2019-08-10-the-soc-controversy.md (renamed from src/_posts/2019-08-10-the-soc-controversy.html)41
-rw-r--r--content/posts/2019/2019-10-17-getting-things-done-with-app-gtd.md (renamed from src/_posts/2019-10-17-getting-thigs-done-with-app-gtd.html)64
-rw-r--r--content/posts/2019/_index.md3
-rw-r--r--content/posts/2020/2020-01-08-running-cgit-on-gentoo.md (renamed from src/_posts/2020-01-08-running-cgit-on-gentoo.md)46
-rw-r--r--content/posts/2020/2020-05-30-setting-up-pgp-wkd.md (renamed from src/_posts/2020-05-30-setting-up-pgp-wkd.md)49
-rw-r--r--content/posts/2020/2020-06-21-lately-in-raku.md (renamed from src/_posts/2020-06-21-lately-in-raku.md)38
-rw-r--r--content/posts/2020/2020-07-15-config-3.0.md (renamed from src/_posts/2020-07-15-config-3.0.md)37
-rw-r--r--content/posts/2020/2020-07-19-freebsd-mailserver-part-6-system-updates.md (renamed from src/_posts/2020-07-19-freebsd-mailserver-part-6-system-updates.md)135
-rw-r--r--content/posts/2020/2020-12-14-raku-modules-in-gentoo-portage.md (renamed from src/_posts/2020-12-14-raku-modules-in-gentoo-portage.md)22
-rw-r--r--content/posts/2020/2020-12-15-merging-json-in-postgresql.md (renamed from src/_posts/2020-12-15-merging-json-in-postgresql.md)20
-rw-r--r--content/posts/2020/_index.md3
-rw-r--r--content/posts/2021/2021-05-13-a-new-irc-client.md (renamed from src/_posts/2021-05-13-a-new-irc-client.md)11
-rw-r--r--content/posts/2021/2021-05-22-raku-on-libera-chat.md (renamed from src/_posts/2021-05-22-raku-on-libera-chat.md)11
-rw-r--r--content/posts/2021/2021-06-04-managing-docker-compose-projects-with-openrc.md (renamed from src/_posts/2021-06-04-managing-docker-compose-projects-with-openrc.md)41
-rw-r--r--content/posts/2021/_index.md3
-rw-r--r--content/posts/2022/2022-02-14-librewolf.md92
-rw-r--r--content/posts/2022/2022-02-20-nginx-tls.md92
-rw-r--r--content/posts/2022/2022-03-05-deprecating-reiserfs.md74
-rw-r--r--content/posts/2022/2022-04-15-fixing-w-in-tremc.md140
-rw-r--r--content/posts/2022/2022-04-23-a-cookbook.md52
-rw-r--r--content/posts/2022/2022-05-07-bashtard-introduction.md265
-rw-r--r--content/posts/2022/2022-08-06-installing-gentoo-encrypted-zfs-efistub.md242
-rw-r--r--content/posts/2022/_index.md3
-rw-r--r--content/posts/2023/2023-02-23-the-woes-of-awsvpnclient.md91
-rw-r--r--content/posts/2023/2023-03-08-using-laminar-for-selfhosted-ci.md64
-rw-r--r--content/posts/2023/2023-03-26-finally-templating-bashtard.md86
-rw-r--r--content/posts/2023/2023-05-23-bashtard-2.0.0.md110
-rw-r--r--content/posts/2023/2023-07-13-getting-emoji-to-work-in-kde-on-debian.md138
-rw-r--r--content/posts/2023/2023-07-24-new-server-rack-mieshu.md89
-rw-r--r--content/posts/2023/2023-08-05-new-server-rack-nouki.md88
-rw-r--r--content/posts/2023/2023-08-29-releasing-raku-modules-with-fez.md74
-rw-r--r--content/posts/2023/_index.md3
-rw-r--r--content/posts/2024/2024-04-02-bashtard-2.1.0.md57
-rw-r--r--content/posts/2024/_index.md3
-rw-r--r--content/posts/_index.md16
-rw-r--r--content/projects/_index.md7
-rw-r--r--content/projects/bashtard/_index.md17
-rw-r--r--content/projects/bashtard/releases/1.0.0.md9
-rw-r--r--content/projects/bashtard/releases/2.0.0.md68
-rw-r--r--content/projects/bashtard/releases/2.0.1.md19
-rw-r--r--content/projects/bashtard/releases/2.0.2.md13
-rw-r--r--content/projects/bashtard/releases/2.1.0.md29
-rw-r--r--content/projects/bashtard/releases/_index.md4
-rw-r--r--content/recipes/_index.md9
-rw-r--r--content/recipes/basics/bechamel.md34
-rw-r--r--content/recipes/condiments/applesauce.md38
-rw-r--r--content/recipes/condiments/mayonnaise.md40
-rw-r--r--content/recipes/condiments/salsa.md59
-rw-r--r--content/recipes/condiments/sauce-mushroom.md65
-rw-r--r--content/recipes/condiments/sriracha.md29
-rw-r--r--content/recipes/dishes-hot/meatball-jordanese.md66
-rw-r--r--content/recipes/dishes-hot/pancakes.md46
-rw-r--r--content/recipes/dishes-hot/soup-mushroom-cream.md68
-rw-r--r--content/recipes/dishes-hot/soup-pea-halal.md86
-rw-r--r--content/recipes/dishes-hot/stew-dutch.md97
-rw-r--r--content/recipes/dishes-side/salad-stewed-beaf.md133
-rw-r--r--content/recipes/dishes-side/stewed-pears.md50
-rw-r--r--content/recipes/dishes-side/waffles.md56
-rw-r--r--content/recipes/snacks/buttercake.md53
-rw-r--r--content/recipes/snacks/cheesecake-basque-burned.md65
-rw-r--r--content/recipes/snacks/kruidnoten.md50
-rw-r--r--content/services/_index.md12
-rw-r--r--content/services/fiche.md12
-rw-r--r--content/services/invidious.md8
-rw-r--r--content/services/nitter.md8
-rw-r--r--content/services/omgur.md9
-rw-r--r--content/services/searxng.md9
-rw-r--r--content/services/teddit.md8
-rw-r--r--layouts/_default/baseof.html54
-rw-r--r--layouts/_default/list.html11
-rw-r--r--layouts/_default/single.html10
-rw-r--r--layouts/_default/term.html19
-rw-r--r--layouts/home.html21
-rw-r--r--layouts/posts/list.html22
-rw-r--r--layouts/posts/list.xml37
-rw-r--r--layouts/posts/single.html36
-rw-r--r--layouts/project-release/list.html14
-rw-r--r--layouts/project-release/list.xml27
-rw-r--r--layouts/project-release/single.html20
-rw-r--r--layouts/projects/list.html21
-rw-r--r--layouts/recipes/list.html24
-rw-r--r--layouts/recipes/single.html103
-rw-r--r--layouts/services/list.html13
-rw-r--r--layouts/services/single.html14
-rw-r--r--layouts/shortcodes/admonition.html8
-rw-r--r--layouts/shortcodes/quote.html10
-rw-r--r--share/feed-atom.xml34
-rw-r--r--share/feed-rss2.xml29
-rw-r--r--src/.docker/envvars.sh14
-rw-r--r--src/.docker/lighttpd.conf29
-rw-r--r--src/.well-known/openpgpkey/hu/i4fxxwcfae1o4d7wnb5bop89yfx399yfbin8306 -> 0 bytes
-rw-r--r--src/.well-known/openpgpkey/policy0
-rw-r--r--src/Dockerfile7
-rw-r--r--src/Gemfile11
-rw-r--r--src/Gemfile.lock100
-rw-r--r--src/README.adoc48
-rw-r--r--src/_config.yml77
-rw-r--r--src/_includes/footer.html19
-rw-r--r--src/_includes/head.html15
-rw-r--r--src/_includes/header.html9
-rw-r--r--src/_includes/posts-intro.md22
-rw-r--r--src/_layouts/archive.html39
-rw-r--r--src/_layouts/default.html12
-rw-r--r--src/_layouts/language-war.html40
-rw-r--r--src/_layouts/post.html51
-rw-r--r--src/_layouts/project.html22
-rw-r--r--src/_pages/blank.md3
-rw-r--r--src/_pages/index.html108
-rw-r--r--src/_pages/posts.html44
-rw-r--r--src/_pages/projects.md60
-rw-r--r--src/_pages/slides.md64
-rw-r--r--src/_pages/support.md44
-rw-r--r--src/_plugins/admonition_md.rb26
-rw-r--r--src/_plugins/highlight.rb127
-rw-r--r--src/_plugins/html-markdown.rb17
-rw-r--r--src/_plugins/jekyll-less.rb9
-rw-r--r--src/_posts/2018-10-11-hackerrank-solutions-python3-and-perl6-part-2.html706
-rw-r--r--src/_projects/assixt.md55
-rw-r--r--src/_projects/config.md7
-rw-r--r--src/_projects/dist-helper.md7
-rw-r--r--src/_projects/io-path-dirstack.md7
-rw-r--r--src/_projects/irc-client-plugin-github.md7
-rw-r--r--src/_projects/irc-client-plugin-ignore.md7
-rw-r--r--src/_projects/irc-client-plugin-nickserv.md7
-rw-r--r--src/_projects/irc-client-plugin-urltitle.md7
-rw-r--r--src/_projects/lonestar.html83
-rw-r--r--src/_projects/mpd-client.md7
-rw-r--r--src/_projects/musashi.md7
-rw-r--r--src/_projects/pod-to-pager.adoc102
-rw-r--r--src/_projects/scriptkitties-overlay.md7
-rw-r--r--src/_projects/string-fold.md7
-rw-r--r--src/_projects/subbot.md7
-rw-r--r--src/_projects/tachikoma.md8
-rw-r--r--src/_slides/perl6-using-app-assixt-to-improve-module-development.md244
-rw-r--r--src/atom.xml34
-rw-r--r--src/atom/assixt.xml34
-rw-r--r--src/atom/caldav.xml34
-rw-r--r--src/atom/carddav.xml34
-rw-r--r--src/atom/cgit.xml34
-rw-r--r--src/atom/cjdns.xml34
-rw-r--r--src/atom/cloudflare.xml34
-rw-r--r--src/atom/codeofconduct.xml34
-rw-r--r--src/atom/conference.xml34
-rw-r--r--src/atom/contributions.xml34
-rw-r--r--src/atom/dkim.xml34
-rw-r--r--src/atom/docker.xml34
-rw-r--r--src/atom/dovecot.xml34
-rw-r--r--src/atom/email.xml34
-rw-r--r--src/atom/encryption.xml34
-rw-r--r--src/atom/freebsd.xml34
-rw-r--r--src/atom/freesoftware.xml34
-rw-r--r--src/atom/funding.xml34
-rw-r--r--src/atom/gentoo.xml34
-rw-r--r--src/atom/gettingthingsdone.xml34
-rw-r--r--src/atom/git.xml34
-rw-r--r--src/atom/github.xml34
-rw-r--r--src/atom/gnu+linux.xml34
-rw-r--r--src/atom/gpg.xml34
-rw-r--r--src/atom/gtk.xml34
-rw-r--r--src/atom/hackerrank.xml34
-rw-r--r--src/atom/hacktoberfest.xml34
-rw-r--r--src/atom/imap.xml34
-rw-r--r--src/atom/letsencrypt.xml34
-rw-r--r--src/atom/lonestar.xml34
-rw-r--r--src/atom/nginx.xml34
-rw-r--r--src/atom/pastebin.xml34
-rw-r--r--src/atom/perl.xml34
-rw-r--r--src/atom/perl6.xml34
-rw-r--r--src/atom/pgp.xml34
-rw-r--r--src/atom/pigeonhole.xml34
-rw-r--r--src/atom/postfix.xml34
-rw-r--r--src/atom/privacy.xml34
-rw-r--r--src/atom/programming.xml34
-rw-r--r--src/atom/python.xml34
-rw-r--r--src/atom/python3.xml34
-rw-r--r--src/atom/raku.xml34
-rw-r--r--src/atom/raspberrypi.xml34
-rw-r--r--src/atom/sasl.xml34
-rw-r--r--src/atom/security.xml34
-rw-r--r--src/atom/spamassassin.xml34
-rw-r--r--src/atom/sparrowdo.xml34
-rw-r--r--src/atom/spf.xml34
-rw-r--r--src/atom/ssl.xml34
-rw-r--r--src/atom/systemd.xml34
-rw-r--r--src/atom/tutorial.xml34
-rw-r--r--src/atom/vpn.xml34
-rw-r--r--src/atom/wkd.xml34
-rw-r--r--src/atom/yubikey.xml34
-rw-r--r--src/css/custom/blockquotes.less18
-rw-r--r--src/css/custom/helpers.less5
-rw-r--r--src/css/custom/navigation.less30
-rw-r--r--src/css/formats/asciidoc.less45
-rw-r--r--src/css/language-war.less69
-rw-r--r--src/css/main.less144
-rw-r--r--src/css/pygments.scss74
-rw-r--r--src/css/variables.less14
-rw-r--r--src/favicon.ico0
-rw-r--r--src/feed.xml29
-rw-r--r--src/feed/assixt.xml29
-rw-r--r--src/feed/caldav.xml29
-rw-r--r--src/feed/carddav.xml29
-rw-r--r--src/feed/cgit.xml29
-rw-r--r--src/feed/cjdns.xml29
-rw-r--r--src/feed/cloudflare.xml29
-rw-r--r--src/feed/codeofconduct.xml29
-rw-r--r--src/feed/conference.xml29
-rw-r--r--src/feed/contributions.xml29
-rw-r--r--src/feed/dkim.xml29
-rw-r--r--src/feed/docker.xml29
-rw-r--r--src/feed/dovecot.xml29
-rw-r--r--src/feed/email.xml29
-rw-r--r--src/feed/encryption.xml29
-rw-r--r--src/feed/freebsd.xml29
-rw-r--r--src/feed/freesoftware.xml29
-rw-r--r--src/feed/funding.xml29
-rw-r--r--src/feed/gentoo.xml29
-rw-r--r--src/feed/gettingthingsdone.xml29
-rw-r--r--src/feed/git.xml29
-rw-r--r--src/feed/github.xml29
-rw-r--r--src/feed/gnu+linux.xml29
-rw-r--r--src/feed/gpg.xml29
-rw-r--r--src/feed/gtk.xml29
-rw-r--r--src/feed/hackerrank.xml29
-rw-r--r--src/feed/hacktoberfest.xml29
-rw-r--r--src/feed/imap.xml29
-rw-r--r--src/feed/letsencrypt.xml29
-rw-r--r--src/feed/lonestar.xml29
-rw-r--r--src/feed/nginx.xml29
-rw-r--r--src/feed/pastebin.xml29
-rw-r--r--src/feed/perl.xml29
-rw-r--r--src/feed/perl6.xml29
-rw-r--r--src/feed/pgp.xml29
-rw-r--r--src/feed/pigeonhole.xml29
-rw-r--r--src/feed/postfix.xml29
-rw-r--r--src/feed/privacy.xml29
-rw-r--r--src/feed/programming.xml29
-rw-r--r--src/feed/python.xml29
-rw-r--r--src/feed/python3.xml29
-rw-r--r--src/feed/raku.xml29
-rw-r--r--src/feed/raspberrypi.xml29
-rw-r--r--src/feed/sasl.xml29
-rw-r--r--src/feed/security.xml29
-rw-r--r--src/feed/spamassassin.xml29
-rw-r--r--src/feed/sparrowdo.xml29
-rw-r--r--src/feed/spf.xml29
-rw-r--r--src/feed/ssl.xml29
-rw-r--r--src/feed/systemd.xml29
-rw-r--r--src/feed/tutorial.xml29
-rw-r--r--src/feed/vpn.xml29
-rw-r--r--src/feed/wkd.xml29
-rw-r--r--src/feed/yubikey.xml29
-rw-r--r--src/robots.txt3
-rw-r--r--static/css/highlight-emacs.css82
-rw-r--r--static/css/highlight-monokai.css82
-rw-r--r--static/img/cc-by-sa.png (renamed from src/img/cc-by-sa.png)bin1621 -> 1621 bytes
-rw-r--r--static/img/email.png (renamed from src/img/email.png)bin1630 -> 1630 bytes
-rw-r--r--static/img/mastodon.png (renamed from src/img/mastodon.png)bin1169 -> 1169 bytes
-rw-r--r--static/js/cookbook.js34
-rw-r--r--static/pubkey.txt (renamed from src/pubkey.txt)0
299 files changed, 5488 insertions, 7832 deletions
diff --git a/.gitignore b/.gitignore
index 6f69780..421e603 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,3 @@
-_site
-.sass-cache
-.jekyll-metadata
-.jekyll-cache
-*.bak
-css/pygments.base.css
-asciidoc-pygments.css
+.hugo_build.lock
+public
+resources/_gen
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index 8ec9421..0000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-stages:
- - build
- - push
-
-build:
- stage: build
- image: ruby:latest
- before_script:
- - gem install bundler:1.17.2
- - bundle install
- script:
- - bundle exec jekyll build
- artifacts:
- paths:
- - _site
-
-push:
- stage: push
- only:
- - master
- image: docker:stable
- services:
- - docker:dind
- variables:
- DOCKER_HOST: tcp://docker:2375
- DOCKER_DRIVER: overlay2
- before_script:
- - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- script:
- - docker build -t $CI_REGISTRY_IMAGE:latest .
- - docker push $CI_REGISTRY_IMAGE:latest
- - docker tag $CI_REGISTRY_IMAGE:latest $CI_REGISTRY_IMAGE:ci-$CI_COMMIT_SHA
- - docker push $CI_REGISTRY_IMAGE:ci-$CI_COMMIT_SHA
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..d909803
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,8 @@
+FROM alpine
+
+RUN apk add --no-cache hugo
+
+WORKDIR /usr/src
+COPY . .
+
+CMD [ "hugo", "serve", "--baseURL", "https://www.tyil.nl","--bind", "::" ]
diff --git a/archetypes/default.md b/archetypes/default.md
new file mode 100644
index 0000000..00e77bd
--- /dev/null
+++ b/archetypes/default.md
@@ -0,0 +1,6 @@
+---
+title: "{{ replace .Name "-" " " | title }}"
+date: {{ .Date }}
+draft: true
+---
+
diff --git a/assets/theme/main.scss b/assets/theme/main.scss
new file mode 100644
index 0000000..967e0da
--- /dev/null
+++ b/assets/theme/main.scss
@@ -0,0 +1,313 @@
+// Variables
+$mainWidth: 900px;
+
+// Colors
+@import url("/css/highlight-emacs.css") screen and (prefers-color-scheme: light);
+@import url("/css/highlight-monokai.css") screen and (prefers-color-scheme: dark);
+
+@media (prefers-color-scheme: light) {
+ :root {
+ --blockBackgroundColor: #c2beb9;
+ --bodyBackgroundColor: #d7d5d1;
+ --bodyForegroundColor: #2a2e2f;
+ --codeBackgroundColor: #f8f8f8;
+ --linkForegroundColor: #1c4253;
+ }
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --blockBackgroundColor: #1c1e1f;
+ --bodyBackgroundColor: #131516;
+ --bodyForegroundColor: #bcb7ae;
+ --codeBackgroundColor: #272822;
+ --linkForegroundColor: #00b3ff;
+ }
+}
+
+// Actual CSS
+html {
+ background-color: var(--bodyBackgroundColor);
+}
+
+body {
+ color: var(--bodyForegroundColor);
+ font-size: 16px;
+ line-height: 1.4;
+ text-align: justify;
+ width: 100%;
+ margin: 0;
+}
+
+small {
+ font-size: 0.7em;
+}
+
+li p {
+ margin: 0;
+}
+
+table {
+ width: 100%;
+}
+
+a.external-link-icon {
+ font-size: x-small;
+ vertical-align: text-top;
+}
+
+a.image-link {
+ text-decoration: none;
+}
+
+span.footer-link-seperator {
+ margin: .5rem;
+ overflow: hidden;
+}
+
+div.container {
+ max-width: $mainWidth;
+ margin: 0 auto 0.5em auto;
+ padding: 1em 2em 0 2em;
+}
+
+span.citneed{
+ vertical-align: top;
+ font-size: 0.7em;
+ padding-left: 0.3em;
+}
+
+p.text-center {
+ text-align: center;
+}
+
+article {
+ footer hr {
+ width: 50%
+ }
+}
+
+section.admonition {
+ background-color: var(--blockBackgroundColor);
+ border: 1px solid var(--bodyForegroundColor);
+ margin: .5rem auto 1.74rem auto;
+ width: 85%;
+ max-width: $mainWidth * .9;
+ padding: 1.5rem;
+
+ .admonition-title {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.5rem;
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
+ }
+
+ p {
+ margin: 0;
+ }
+}
+
+section.project {
+ border-top: 1px solid var(--bodyForegroundColor);
+ padding: 0.5rem 0.5rem;
+
+ h2 {
+ margin: 0.5rem 0rem;
+
+ small {
+ margin-left: 1.5rem;
+ font-weight: normal;
+ font-size: small;
+ }
+ }
+
+ p {
+ margin-top: 0;
+ }
+
+ nav.project {
+ a, a:visited {
+ margin: 0.5rem;
+ text-decoration: underline;
+ color: var(--bodyForegroundColor);
+ }
+
+ a::before {
+ content: "» ";
+ }
+ }
+}
+
+section.recipe {
+ border-top: 1px solid var(--bodyForegroundColor);
+ padding: 0.5rem;
+ display: grid;
+ grid-template-columns: [preview] 1fr [description] 5fr [end];
+
+ div.picture {
+ grid-column-start: preview;
+ grid-column-end: description;
+ }
+
+ div.description {
+ grid-column-start: description;
+ grid-column-end: end;
+ }
+
+ h2 {
+ margin: 0.5rem 0rem;
+ }
+}
+
+section.service {
+ border-top: 1px solid var(--bodyForegroundColor);
+ padding: 0.5rem;
+
+ h2 {
+ margin: 0.5rem 0rem;
+
+ small {
+ margin-left: 1.5rem;
+ font-weight: normal;
+ font-size: small;
+ }
+ }
+
+ p {
+ margin-top: 0;
+ }
+}
+
+@media(min-width: $mainWidth) {
+ section.admonition {
+ display: grid;
+
+ grid-template-columns: [title] .25fr [body] 1fr [end];
+
+ .admonition-title {
+ grid-column-start: title;
+ grid-column-end: body;
+ }
+
+ p {
+ grid-column-start: body;
+ grid-column-end: end;
+
+ padding-left: 10px;
+ border-left: 1px solid #ddd;
+ }
+ }
+}
+
+@media(max-width: $mainWidth) {
+ section.admonition {
+ .admonition-title {
+ text-align: center;
+ margin-top: 0;
+ }
+
+ p {
+ padding-top: 10px;
+ border-top: 1px solid #ddd;
+ }
+ }
+}
+
+// Navigation bar
+nav.main {
+ padding-bottom: 8px;
+ border-bottom: double var(--bodyForegroundColor);
+ text-align: center;
+ font-family: Sans;
+
+ a, a:visited {
+ margin: 0 0.5em;
+ font-size: 24px;
+ text-decoration: none;
+ color: var(--bodyForegroundColor);
+ }
+
+ .brand-name {
+ text-align: center;
+ display: block;
+ font-weight: bold;
+ font-size: 32px;
+ color: var(--bodyForegroundColor);
+ margin-bottom: 8px;
+ }
+}
+
+// Generic links
+a, a:visited {
+ color: var(--linkForegroundColor);
+}
+
+// Syntax highlighting
+div.highlight {
+ border: 2px solid var(--bodyForegroundColor);
+ background-color: var(--codeBackgroundColor);
+ width: 90%;
+ margin: 0 auto;
+ overflow-x: auto;
+
+ pre {
+ margin: 0;
+ padding: 6px 6px;
+ }
+
+ .code-link {
+ border-top: 1px dotted var(--bodyForegroundColor);
+ padding: 3px 8px;
+ text-align: right;
+ }
+}
+
+code {
+ padding: 2px;
+}
+
+pre code {
+ padding: 0;
+}
+
+// Helper classes
+.center {
+ text-align: center;
+}
+
+.quoteblock {
+ width: 90%;
+ margin: .5rem auto;
+ border-left: double black;
+ padding: 0.5em;
+ background-color: var(--blockBackgroundColor);
+
+ blockquote {
+ font-style: italic;
+ }
+
+ div.attribution {
+ text-align: right;
+ margin-right: 1em;
+ }
+}
+
+.tag {
+ color: var(--linkForegroundColor);
+ font-family: monospace;
+ text-decoration: none;
+ border-bottom: 1px dotted var(--linkForegroundColor);
+}
+.tag::before {
+ content: "#";
+}
+
+ul.taglist {
+ li {
+ display: inline;
+ }
+
+ margin: 0;
+ padding: 0;
+}
diff --git a/bin/make-docker b/bin/make-docker
deleted file mode 100755
index 9a1a156..0000000
--- a/bin/make-docker
+++ /dev/null
@@ -1,16 +0,0 @@
-#! /usr/bin/env perl6
-
-use v6.c;
-
-#| Create a docker image of the blog.
-sub MAIN (
- #| The tag to use for the docker image.
- Str:D :$tag = "tyil/blog:latest",
-) {
- my IO::Path $basedir = $*PROGRAM.resolve.parent(2);
- chdir $basedir;
-
- run « bundle »;
- run « bundle exec jekyll build »;
- run « docker build -t "$tag" . »;
-}
diff --git a/bin/make-feeds b/bin/make-feeds
deleted file mode 100755
index d8df2c9..0000000
--- a/bin/make-feeds
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/sh
-
-# This program is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Affero General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
-# details.
-
-readonly ROOTDIR="$(CDPATH="" cd -- "$(dirname -- "$0")/.." && pwd -P)"
-
-main()
-{
- # Handle opts
- while getopts ":h" opt
- do
- case "$opt" in
- h) usage && exit 0 ;;
- *)
- printf "Invalid option passed: %s\n" "$OPTARG" >&2
- ;;
- esac
- done
-
- shift $(( OPTIND - 1 ))
-
- # Make a list of all unique tags
- tags="$(mktemp)"
- awk '/^tags:/ { for (i=2; i<=NF; i++) print $i }' "$ROOTDIR/src/_posts/"* \
- | sort \
- | uniq \
- > "$tags"
-
- # Create a feed for each tag
- mkdir -p -- "$ROOTDIR/src/feed"
- mkdir -p -- "$ROOTDIR/src/atom"
-
- while read -r tag
- do
- lc_tag="$(printf "%s" "$tag" | tr "[:upper:]" "[:lower:]")"
-
- echo "Creating RSS 2.0 feed for $lc_tag"
- TAG="$tag" envsubst < "$ROOTDIR/share/feed-rss2.xml" > "$ROOTDIR/src/feed/$lc_tag.xml"
-
- echo "Creating Atom feed for $lc_tag"
- TAG="$tag" envsubst < "$ROOTDIR/share/feed-atom.xml" > "$ROOTDIR/src/atom/$lc_tag.xml"
-
- unset lc_tag
- done < "$tags"
-
- # Clean up
- rm -f -- "$tags"
-}
-
-usage()
-{
- cat <<EOF
-Usage:
- ${0##*/} -h
-
-Generate all the seperate feeds for each tag used in posts.
-
-Options:
- -h Show this help text and exit.
-EOF
-}
-
-main "$@"
diff --git a/bin/make-mimetypes b/bin/make-mimetypes
deleted file mode 100755
index 64c9120..0000000
--- a/bin/make-mimetypes
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env perl6
-
-use v6.c;
-
-sub MAIN (
- Str:D :$default = "application/octet-stream",
-) {
- my IO::Path $mime-types = "/etc/mime.types".IO;
-
- die "No $mime-types.absolute()" unless $mime-types.f;
-
- my %types;
-
- for $mime-types.lines -> $line {
- my ($mimetype, @extensions) = $line.words;
-
- for @extensions -> $extension {
- %types{$extension} = $mimetype;
- }
- }
-
- print-conf(%types, $default);
-}
-
-sub print-conf (
- %mimetypes,
- Str:D $default,
-) {
- say "mimetype.assign = (";
-
- for %mimetypes.kv -> $extension, $type {
- say "\t\".$extension\" => \"$type\",";
- }
-
- say "\"\" => \"$default\"\n)";
-}
diff --git a/bin/publish b/bin/publish
deleted file mode 100755
index e53541e..0000000
--- a/bin/publish
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-
-# This program is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Affero General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
-# details.
-
-readonly BASEDIR="$(CDPATH="" cd -- "$(dirname -- "$0")/.." && pwd -P)"
-
-main()
-{
- # Handle opts
- while getopts ":h" opt
- do
- case "$opt" in
- h) usage && exit 0 ;;
- *)
- printf "Invalid option passed: %s\n" "$OPTARG" >&2
- ;;
- esac
- done
-
- shift $(( OPTIND - 1 ))
-
- if [ $# -lt 1 ]
- then
- printf "Must specify a directory to publish the site at\n"
- exit 3
- fi
-
- output=$1
-
- # Ensure output directory exists
- if [ ! -d "$output" ]
- then
- printf "No such directory: %s\n" "$output"
- exit 4
- fi
-
- # Make ZFS snapshot
- if awk '$3 == "zfs" { print $2 }' < /proc/mounts | grep -q "$output"
- then
- zfs_subvol="$(zfs list -o name,mountpoint | awk '$2 == "'"$output"'" { print $1 }')"
- zfs_snapshot="$zfs_subvol@$(date +%FT%T)"
-
- printf "Creating ZFS snapshot %s\n" "$zfs_snapshot"
-
- sudo zfs snapshot "$zfs_snapshot"
- fi
-
- # Publish new site source
- cd -- "$BASEDIR/src"
- bundle install
- bundle exec jekyll build -d "$output"
-}
-
-usage()
-{
- cat <<EOF
-Usage:
- ${0##*/} -h
-
-Nondescript
-
-Options:
- -h Show this help text and exit.
-EOF
-}
-
-main "$@"
diff --git a/config.toml b/config.toml
new file mode 100644
index 0000000..3a6a07e
--- /dev/null
+++ b/config.toml
@@ -0,0 +1,13 @@
+baseURL = "https://www.tyil.nl/"
+languageCode = "en-us"
+title = "Tyil"
+assetDir = "assets"
+enableRobotsTXT = true
+
+[markup.highlight]
+noClasses = false
+codeFences = true
+tabwidth = 8
+
+[permalinks]
+posts = "/post/:year/:month/:day/:title/"
diff --git a/content/_index.md b/content/_index.md
new file mode 100644
index 0000000..ec0ccd7
--- /dev/null
+++ b/content/_index.md
@@ -0,0 +1,94 @@
+---
+title: About Me
+---
+
+Freedom-focused hacker. I love everything about free software, and spend much
+time contributing to it myself. I occasionally write blog posts to help other
+people getting started with free software, show the issues with proprietary
+software, or just talk about something I find fun and interesting.
+
+Pretty much all of my projects can be found on
+[git.tyil.nl](https://git.tyil.nl), though many of them are also mirrored on
+other code forges.
+
+I can be reached through various means of communication, though all of them
+usable by completely free means. Scroll down to the **Channels** section for
+more information about that.
+
+## Contact
+
+### PGP
+
+My public PGP key is available [from my own site][pubkey], or from a public key
+server such as [pgp.mit.edu][pubkey-mit]. The fingerprint is:
+
+ 1660 F6A2 DFA7 5347 322A 4DC0 7A6A C285 E2D9 8827
+
+You can also fetch my PGP key using the
+[WebKey Protocol](/post/2020/05/30/setting-up-pgp-wkd/):
+
+ gpg --locate-key p.spek@tyil.nl
+
+[pubkey]: /pubkey.txt
+[pubkey-mit]: http://pgp.mit.edu/pks/lookup?op=vindex&search=0x7A6AC285E2D98827
+
+### Channels
+
+#### Email
+
+Email contact goes via [p.spek@tyil.nl][mail]. Be sure to at least sign all
+mail you send me. Even better would be encrypted mail using my [PGP
+key][pubkey].
+
+I do not read my mailboxes very often, so please do not expect a timely
+response. If you require a response as soon as possible, please find me on IRC
+instead.
+
+#### Fediverse
+
+I host my own MissKey instance to interact with the wider Fediverse.
+
+- [`@tyil@fedi.tyil.nl`](https://fedi.tyil.nl/@tyil)
+
+#### IRC
+
+I am active on various IRC networks, most often under the nick `tyil`. All of
+these are connected from the same client, so you can pick any of these if you
+wish to have a real-time chat with me.
+
+- [DareNET](https://darenet.org)
+- [Libera](https://libera.chat)
+- [OFTC](https://www.oftc.net/)
+- [Rizon](https://rizon.net)
+
+#### Matrix
+
+As the years have gone by, I've been losing faith in Matrix more and more. I
+still have an account, and I would be happy if it ever got good, but I
+personally am not counting on that to happen anymore.
+
+- `@tyil:matrix.org`
+
+#### XMPP
+
+If IRC is not your thing, I can be reached for personal chats on XMPP too.
+
+- `tyil@disroot.org`
+- `tyil@chat.tyil.nl`
+
+## Other links
+
+- [Sourcehut account][git-srht]
+- [GitLab account][git-gl]
+- [GitHub account][git-gh]
+
+## RSS
+
+If you'd like to stay up-to-date with my posts, you can subscribe to the [RSS
+feed](/posts/index.xml).
+
+[git-gh]: https://github.com/tyil
+[git-gl]: https://gitlab.com/tyil
+[git-srht]: https://sr.ht/~tyil/
+[mail]: mailto:p.spek@tyil.nl
+[pubkey]: /pubkey.txt
diff --git a/content/http-404.md b/content/http-404.md
new file mode 100644
index 0000000..a0fd734
--- /dev/null
+++ b/content/http-404.md
@@ -0,0 +1,6 @@
+---
+title: "HTTP 404: File Not Found"
+url: http-404.html
+---
+
+The file you were looking for could not be found.
diff --git a/src/_posts/2016-10-01-on-pastebin.md b/content/posts/2016/2016-10-01-on-pastebin.md
index b5cab12..cb54542 100644
--- a/src/_posts/2016-10-01-on-pastebin.md
+++ b/content/posts/2016/2016-10-01-on-pastebin.md
@@ -1,9 +1,11 @@
---
-layout: post
-date: 2016-10-01 10:20:27 +0200
-tags: Pastebin Security Cloudflare Privacy
-authors:
- - ["Patrick Spek", "http://tyil.work"]
+date: 2016-10-01
+title: On Pastebin
+tags:
+- Pastebin
+- Security
+- Cloudflare
+- Privacy
---
Pastebin offers itself as a gratis paste service. Although it is probably the
diff --git a/src/_posts/2016-10-01-on-systemd.md b/content/posts/2016/2016-10-01-on-systemd.md
index 9dc410a..9bd46d8 100644
--- a/src/_posts/2016-10-01-on-systemd.md
+++ b/content/posts/2016/2016-10-01-on-systemd.md
@@ -1,10 +1,10 @@
---
-layout: post
-date: 2016-10-01 10:20:27 +0200
-tags: Systemd Security GNU+Linux
-authors:
- - ["Patrick Spek", "http://tyil.work"]
- - ["Samantha McVey", "https://cry.nu"]
+date: 2016-10-01
+title: On Systemd
+tags:
+- Systemd
+- Security
+- GNU+Linux
---
Systemd once presented itself as being the next generation init system for
diff --git a/src/_posts/2016-10-25-setup-a-vpn-with-cjdns.md b/content/posts/2016/2016-10-25-setup-a-vpn-with-cjdns.md
index 74446b0..52d9237 100644
--- a/src/_posts/2016-10-25-setup-a-vpn-with-cjdns.md
+++ b/content/posts/2016/2016-10-25-setup-a-vpn-with-cjdns.md
@@ -1,10 +1,12 @@
---
+date: 2016-10-25
title: Setup a VPN with cjdns
-date: 2016-10-25 08:00:34
-tags: Tutorial VPN cjdns GNU+Linux FreeBSD
-layout: post
-authors:
- - ["Patrick Spek", "http://tyil.work"]
+tags:
+- Tutorial
+- VPN
+- cjdns
+- GNU+Linux
+- FreeBSD
---
In this tutorial I will outline a simple setup for a [VPN][vpn] using
@@ -23,39 +25,39 @@ may have to update some steps to work on your environment in that case.
Before you can begin, we need some dependencies. There's only two of those, and
they are available via `pkg` to make it even easier. Install them as follows:
-{% highlight sh %}
+```
pkg install gmake node
-{% endhighlight %}
+```
### Compiling
Next up is getting the cjdns sources and compile these, as cjdns is not
available as a prebuilt package:
-{% highlight sh %}
+```
mkdir -p ~/.local/src
cd $_
git clone https://github.com/cjdelisle/cjdns.git cjdns
cd $_
./do
-{% endhighlight %}
+```
To make the compiled binary available system-wide so we can use it with a
system service, copy it to `/usr/local/bin` and rehash to make it available as
a direct command:
-{% highlight sh %}
+```
cp cjdroute /usr/local/bin/.
hash -r
-{% endhighlight %}
+```
### Configuring
Cjdns provides a flag to generate the initial configuration. This will provide
you with some sane defaults where only a couple of small changes are needed to
make it work properly. Generate these defaults with `--genconf`:
-{% highlight sh %}
+```
(umask 177 && cjdroute --genconf > /usr/local/etc/cjdroute.conf)
-{% endhighlight %}
+```
The umask will make all following commands write files using `600` permissions.
This makes sure the config file is not readable by people who shouldn't be able
@@ -67,13 +69,13 @@ and remove the contents of it. Then you can add your own machines in it. This
guide follows the assumption of two clients, so the config for two clients will
be shown here. You can add more clients if you wish, ofcourse.
-{% highlight json %}
+```json
"authorizedPasswords":
[
{"password": "aeQu6pa4Vuecai3iebah7ogeiShaeDaepha6Mae1yooThoF0oa0Eetha9oox", "user": "client_1"},
{"password": "aiweequuthohkahx4tahLohPiezee9OhweiShoNeephe0iekai2jo9Toorah", "user": "client_2"},
]
-{% endhighlight %}
+```
If you need to generate a password, you can make use of the tool `pwgen`,
available at your local package manager. You can then generate new passwords by
@@ -86,8 +88,8 @@ This in turn allows you to enable a service at startup. This way you can make
sure cjdns starts whenever the server boots. You can copy the following
contents directly into `/usr/local/etc/rc.d/cjdroute`:
-{% highlight sh %}
-#! /bin/sh
+```sh
+#!/bin/sh
# PROVIDE: cjdroute
# KEYWORD: shutdown
@@ -110,13 +112,13 @@ command="/usr/local/bin/cjdroute"
command_args=" < ${cjdroute_config}"
run_rc_command "$1"
-{% endhighlight %}
+```
Afterwards, you must enable the service in `/etc/rc.conf.local` like follows:
-{% highlight sh %}
+```
echo 'cjdroute_enable="YES"' >> /etc/rc.conf.local
-{% endhighlight %}
+```
## Installation of the clients
### Dependencies
@@ -124,9 +126,9 @@ The dependencies are still on `gmake` and `node`, so simply install those on
your clients. This guide assumes using Funtoo for the clients, so installation
would go as follows:
-{% highlight sh %}
+```
emerge gmake nodejs
-{% endhighlight %}
+```
### Compiling
Compilation is the same as for the server, so check back there for more
@@ -138,9 +140,9 @@ just like on the server. On Funtoo, config files generally reside in `/etc`
instead of `/usr/local/etc`, so you should set the filepath you write the
configuration to accordingly:
-{% highlight sh %}
+```
cjdroute --genconf > /etc/cjdroute.conf
-{% endhighlight %}
+```
Setting up the connections differs as well, as the clients are going to make an
outbound connection to the server, which is configured to accept inbound
@@ -157,7 +159,7 @@ server's `cjdroute.conf` file.
On client 1, put the following in your `cjdroute.conf`:
-{% highlight json %}
+```json
"connectTo":
{
"192.168.1.1:9416":
@@ -167,11 +169,11 @@ On client 1, put the following in your `cjdroute.conf`:
"publicKey": "thisIsJustForAnExampleDoNotUseThisInYourConfFile_1.k"
}
}
-{% endhighlight %}
+```
On client 2:
-{% highlight json %}
+```json
"connectTo":
{
"192.168.1.1:9416":
@@ -181,7 +183,7 @@ On client 2:
"publicKey": "thisIsJustForAnExampleDoNotUseThisInYourConfFile_1.k"
}
}
-{% endhighlight %}
+```
That is all for configuring the nodes.
@@ -191,16 +193,16 @@ your VPN. For openrc based systems, such as Funtoo, cjdns comes with a ready to
use service script. To make this available to your system, copy it over to the
right directory:
-{% highlight sh %}
+```
cp ~/.local/src/cjdns/contrib/openrc/cjdns /etc/init.d/cjdroute
-{% endhighlight %}
+```
Now add the service to system startup and start the service:
-{% highlight sh %}
+```
rc-update add cjdroute default
rc-service cjdroute start
-{% endhighlight %}
+```
That should be sufficient to get cjdns up and running for an encrypted VPN. You
can find the IPs of each of your systems at the top of your `cjdroute.conf`
@@ -208,4 +210,3 @@ files, in the `ipv6` attribute.
[cjdns]: https://github.com/cjdelisle/cjdns
[vpn]: https://en.wikipedia.org/wiki/Virtual_private_network
-
diff --git a/src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md b/content/posts/2016/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md
index a2802f8..8c7caa0 100644
--- a/src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md
+++ b/content/posts/2016/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md
@@ -1,10 +1,12 @@
---
+date: 2016-10-25
title: Setup nginx with Let's Encrypt SSL
-date: 2016-10-25 08:00:34
-tags: Tutorial LetsEncrypt Nginx SSL Encryption
-layout: post
-authors:
- - ["Patrick Spek", "http://tyil.work"]
+tags:
+- Tutorial
+- LetsEncrypt
+- Nginx
+- SSL
+- Encryption
---
This is a small tutorial to setup nginx with Let's Encrypt on a FreeBSD server
@@ -14,9 +16,9 @@ to host a static site.
First you have to install all the packages we need in order to get this server
going:
-{% highlight sh %}
+```sh
pkg install nginx py27-certbot
-{% endhighlight %}
+```
## Configure nginx
Next is nginx. To make life easier, you should configure nginx to read all
@@ -27,7 +29,7 @@ nginx installations on GNU+Linux distributions, but not default on FreeBSD.
Open up `/usr/local/etc/nginx/nginx.conf` and make the contents of the `http`
block look a as follows:
-{% highlight nginx %}
+```nginx
http {
include mime.types;
default_type application/octet-stream;
@@ -76,7 +78,7 @@ http {
# include site-specific configs
include sites/*.conf;
}
-{% endhighlight %}
+```
This sets default ssl settings for all server blocks that enable ssl. Note that
these are settings I use, and are in no way guaranteed to be perfect. I did some
@@ -93,7 +95,7 @@ easy.
Put the following in `/usr/local/etc/nginx/sites/domain.conf`:
-{% highlight nginx %}
+```nginx
# static HTTP
server {
# listeners
@@ -112,7 +114,7 @@ server {
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
}
-{% endhighlight %}
+```
If your site's sources do not reside in `/srv/www/domain/_site`, change the
path accordingly. This guide will continue using this path for all examples, so
@@ -123,25 +125,25 @@ will be used. Modify this to your own domain.
Nginx is now configured to host a single site over HTTP. Now is the time to enable
the nginx service. Execute the following:
-{% highlight sh %}
+```sh
echo 'nginx_enable="YES"' >> /etc/rc.conf.local
-{% endhighlight %}
+```
This will enable nginx as a system service. On reboots, it will be started
automatically. You can also start it up without rebooting by running the
following:
-{% highlight sh %}
+```sh
service nginx start
-{% endhighlight %}
+```
## Configure Let's Encrypt
Nginx is now running as your web server on port 80. Now you can request Let's
Encrypt certificates using `certbot`. You can do so as follows:
-{% highlight sh %}
+```sh
certbot certonly --webroot -w /srv/www/domain/_site -d domain.tld -d www.domain.tld
-{% endhighlight %}
+```
In case you want to add any sub domains, simply add more `-d sub.domain.tld`
arguments at the end. If the DNS entries for the domains resolve properly, and
@@ -163,7 +165,7 @@ re-configure your site on nginx to host the HTTPS version of your site instead.
Open up `/usr/local/etc/nginx/sites/domain.conf` again, and make the contents
look like the following:
-{% highlight nginx %}
+```nginx
# redirect HTTPS
server {
# listeners
@@ -195,16 +197,16 @@ server {
ssl_certificate /usr/local/etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/domain.tld/privkey.pem;
}
-{% endhighlight %}
+```
Do not forget to update all the paths to match your setup!
As a final step, you should generate the dhparam file. This is to avoid the
issues as described on [Weak DH][weakdh].
-{% highlight sh %}
+```sh
openssl gendh -out /usr/local/etc/ssl/dhparam.pem 4096
-{% endhighlight %}
+```
Be aware that this step can take a **very** long time. On the test machine I
used to test this tutorial, with 1 core and 1 GB ram, it took nearly 1 hour to
@@ -215,9 +217,9 @@ The final step is to reload the nginx configuration so it hosts the SSL version
of your site, and redirects the HTTP version to the HTTPS version. To do this,
simply run
-{% highlight sh %}
+```sh
service nginx reload
-{% endhighlight %}
+```
That should be all to get your site working with HTTP redirecting to HTTPS, and
HTTPS running using a gratis Let's Encrypt certificate.
@@ -225,4 +227,3 @@ HTTPS running using a gratis Let's Encrypt certificate.
[contact]: https://www.tyil.work/
[ssllabs]: https://www.ssllabs.com/ssltest/analyze.html?d=tyil.work&latest
[weakdh]: https://weakdh.org/
-
diff --git a/src/_posts/2016-10-31-freebsd-mailserver-part-1-preparations.md b/content/posts/2016/2016-10-31-freebsd-mailserver-part-1-preparations.md
index 2439349..9fc04e7 100644
--- a/src/_posts/2016-10-31-freebsd-mailserver-part-1-preparations.md
+++ b/content/posts/2016/2016-10-31-freebsd-mailserver-part-1-preparations.md
@@ -1,8 +1,10 @@
---
-title: "FreeBSD email server - Part 1: Preparations"
date: 2016-10-31 07:57:50
-tags: Tutorial FreeBSD Email
-layout: post
+title: "FreeBSD email server - Part 1: Preparations"
+tags:
+- Tutorial
+- FreeBSD
+- Email
---
This tutorial is devised into multiple chapters to make it more manageable, and
@@ -42,19 +44,19 @@ interface for this task.
### Installation
Since the tutorial uses FreeBSD 11, you can install PostgreSQL easily by running
-{% highlight sh %}
+```
pkg install postgresql96-server
-{% endhighlight %}
+```
### Starting up
In order to start Postfix, you should enable the system service for it. This
way, `service` can be used to easily manage it. In addition, it will start
automatically on boot.
-{% highlight sh %}
+```
echo 'postgresql_enable="YES"' >> /etc/rc.conf.local
service postgresql start
-{% endhighlight %}
+```
### Database initialization
Since PostgreSQL is a little different than the more popular [MySQL][mysql], I
@@ -62,32 +64,32 @@ will guide you through setting up the database as well. To begin, switch user
to `postgres`, which is the default administrative user for PostgreSQL. Then
simply open up the PostgreSQL CLI.
-{% highlight sh %}
+```
su postgres
psql
-{% endhighlight %}
+```
Once you are logged in to PostgreSQL, create a new user which will hold
ownership of the database and make a database for this user.
-{% highlight sql %}
+```sql
CREATE USER postfix WITH PASSWORD 'incredibly-secret!';
CREATE DATABASE mail WITH OWNER postfix;
-{% endhighlight %}
+```
Once this is done, create the tables which will hold some of our configuration
data.
#### domains
-{% highlight sql %}
+```sql
CREATE TABLE domains (
name VARCHAR(255) NOT NULL,
PRIMARY KEY (name)
);
-{% endhighlight %}
+```
#### users
-{% highlight sql %}
+```sql
CREATE TABLE users (
local VARCHAR(64) NOT NULL,
domain VARCHAR(255) NOT NULL,
@@ -95,10 +97,10 @@ CREATE TABLE users (
PRIMARY KEY (local, domain),
FOREIGN KEY (domain) REFERENCES domains(name) ON DELETE CASCADE
);
-{% endhighlight %}
+```
#### aliases
-{% highlight sql %}
+```sql
CREATE TABLE aliases (
domain VARCHAR(255),
origin VARCHAR(256),
@@ -106,25 +108,25 @@ CREATE TABLE aliases (
PRIMARY KEY (origin, destination),
FOREIGN KEY (domain) REFERENCES domains(name) ON DELETE CASCADE
);
-{% endhighlight %}
+```
## Let's Encrypt
### Installation
Installing the [Let's Encrypt][letsencrypt] client is just as straightforward
as the PostgreSQL database, using `pkg`.
-{% highlight sh %}
+```
pkg install py27-certbot
-{% endhighlight %}
+```
### Getting a certificate
Requesting a certificate requires your DNS entries to properly resolve. If they
do not resolve yet, Let's Encrypt will bother you with errors. If they do
resolve correctly, use `certbot` to get your certificate.
-{% highlight sh %}
+```
certbot certonly --standalone -d domain.tld
-{% endhighlight %}
+```
## Conclusion
This should be everything required to get started on setting up your own email
@@ -134,5 +136,5 @@ Postfix.
[freebsd]: https://www.freebsd.org/
[letsencrypt]: https://letsencrypt.org/
[mysql]: https://www.mysql.com/
-[part-2]: {{ "/post/2016/10/31/freebsd-mailserver-part-2-mailing-with-postfix/" | prepend: site.baseurl }}
+[part-2]: /post/2016/10/31/freebsd-mailserver-part-2-mailing-with-postfix/
[postgres]: https://www.postgresql.org/
diff --git a/src/_posts/2016-10-31-freebsd-mailserver-part-2-mailing-with-postfix.md b/content/posts/2016/2016-10-31-freebsd-mailserver-part-2-mailing-with-postfix.md
index 1818c9b..58d822f 100644
--- a/src/_posts/2016-10-31-freebsd-mailserver-part-2-mailing-with-postfix.md
+++ b/content/posts/2016/2016-10-31-freebsd-mailserver-part-2-mailing-with-postfix.md
@@ -1,8 +1,11 @@
---
+date: 2016-10-31
title: "FreeBSD email server - Part 2: Mailing with Postfix"
-date: 2016-10-31 07:57:50
-tags: Tutorial FreeBSD Email Postfix
-layout: post
+tags:
+- Tutorial
+- FreeBSD
+- Email
+- Postfix
---
Welcome to the second part of my FreeBSD email server series. In this series, I
@@ -307,7 +310,7 @@ Dovecot, which will enable IMAP. It will also provide the SASL mechanism
defined in this part.
[freebsd-ports]: https://www.freebsd.org/ports/
-[home]: {{ "/" | prepend: site.baseurl }}
-[part-1]: {{ "/post/2016/10/31/freebsd-mailserver-part-1-preparations/" | prepend: site.baseurl }}
+[home]: /
+[part-1]: /post/2016/10/31/freebsd-mailserver-part-1-preparations/
[postfix]: http://www.postfix.org/
[sendmail]: http://www.sendmail.com/sm/open_source/
diff --git a/src/_posts/2016-10-31-freebsd-mailserver-part-3-dovecot-imap-sasl.md b/content/posts/2016/2016-10-31-freebsd-mailserver-part-3-dovecot-imap-sasl.md
index cbb476b..0938a5e 100644
--- a/src/_posts/2016-10-31-freebsd-mailserver-part-3-dovecot-imap-sasl.md
+++ b/content/posts/2016/2016-10-31-freebsd-mailserver-part-3-dovecot-imap-sasl.md
@@ -1,8 +1,13 @@
---
-title: "FreeBSD email server - Part 3: Dovecot, IMAP and SASL"
date: 2016-10-31 07:57:50
-tags: Tutorial FreeBSD Email Dovecot IMAP SASL
-layout: post
+title: "FreeBSD email server - Part 3: Dovecot, IMAP and SASL"
+tags:
+- Tutorial
+- FreeBSD
+- Email
+- Dovecot
+- IMAP
+- SASL
---
Welcome to the second part of my FreeBSD email server series. In this series, I
@@ -27,10 +32,10 @@ ports tree will be omitted here.
You can start the installation procedure with the following commands.
-{% highlight sh %}
+```
cd /usr/ports/mail/dovecot2
make configure install
-{% endhighlight %}
+```
Again, like with the Postfix installation, leave the default options on and add
the `PGSQL` option so Dovecot can use PostgreSQL as the database back-end.
@@ -38,16 +43,16 @@ the `PGSQL` option so Dovecot can use PostgreSQL as the database back-end.
## Enabling Dovecot
Enable the Dovecot service for rcinit.
-{% highlight sh %}
+```
echo 'dovecot_enable="YES"' >> /etc/rc.conf.local
-{% endhighlight %}
+```
## Configuring Dovecot
To start of with Dovecot configuration, copy over the sample files first.
-{% highlight sh %}
+```
cp -r /usr/local/etc/dovecot/example-config/* /usr/local/etc/dovecot/.
-{% endhighlight %}
+```
Now you can start editing a number of pesky files. The file names of the
headings all appear relative to `/usr/local/etc/dovecot`.
@@ -56,9 +61,9 @@ headings all appear relative to `/usr/local/etc/dovecot`.
Here you only have to set which protocols you want to enable. Set them as
follows.
-{% highlight ini %}
+```ini
protocols = imap lmtp
-{% endhighlight %}
+```
### conf.d/10-master.cf
The `master.cf` configuration file indicates which sockets Dovecot should use
@@ -68,7 +73,7 @@ they are, with the exception of the following two blocks.
#### service imap-login
This will enable imaps, IMAP over SSL, and disable plain IMAP.
-{% highlight ini %}
+```ini
service-imap-login {
inet_listener imap {
port = 0
@@ -79,14 +84,14 @@ service-imap-login {
ssl = yes
}
}
-{% endhighlight %}
+```
#### services
This will instruct Dovecot to provide a service for authentication and `lmtp`
the **local mail transport protocol**. This is required to deliver the email
files into the correct email box location in the file system.
-{% highlight ini %}
+```ini
service auth {
unix_listener auth-userdb {
mode = 0600
@@ -114,34 +119,34 @@ service lmtp {
service auth-worker {
user = postfix
}
-{% endhighlight %}
+```
### conf.d/10-ssl.conf
Here you have to enable SSL and provide the correct paths to your SSL key in
order for Dovecot to work with them.
-{% highlight ini %}
+```ini
ssl = required
ssl_cert = < /usr/local/etc/letsencrypt/live/domain.tld/fullchain.pem
ssl_key = < /usr/local/etc/letsencrypt/live/domain.tld/privkey.pem
-{% endhighlight %}
+```
### conf.d/10-mail.conf
The mail.conf location instructs Dovecot which location to appoint for storing
the email files. `%d` expands to the domain name, while `%n` expands to the
local part of the email address.
-{% highlight ini %}
+```ini
mail_home = /srv/mail/%d/%n
mail_location = maildir:~/Maildir
-{% endhighlight %}
+```
Make sure the location set by `mail_home` exists and is owned by `postfix`!
-{% highlight sh %}
+```
mkdir -p /srv/mail
chown postfix:postfix /srv/mail
-{% endhighlight %}
+```
### conf.d/10-auth.conf
This file deals with the authentication provided by Dovecot. Mostly, which
@@ -149,10 +154,10 @@ mechanisms should be supported and what mechanism should be used to get the
actual credentials to check against. Make sure the following options are set
as given
-{% highlight ini %}
+```ini
disable_plaintext_auth = yes
-auth_mechanisms = plain
-{% endhighlight %}
+auth_mechanisms = plain
+```
Also, make sure `!include auth-system.conf.ext` is commented **out**. It is not
commented out by default, so you will have to do this manually. In addition,
@@ -162,7 +167,7 @@ you have to uncomment `!include auth-sql.conf.ext`.
This is the file included from `10-auth.conf`. It instructs Dovecot to use SQL as
the driver for the password and user back-ends.
-{% highlight ini %}
+```ini
passdb {
driver = sql
args = /usr/local/etc/dovecot/dovecot-sql-conf.ext
@@ -176,7 +181,7 @@ userdb {
driver = sql
args = /usr/local/etc/dovecot/dovecot-sql-conf.ext
}
-{% endhighlight %}
+```
### dovecot-sql.conf.ext
The final configuration file entails the queries which should be used to get the
@@ -189,7 +194,7 @@ As a side note, if you are following this tutorial on a machine that does
setup, you **can not** use `BLF-CRYPT` as the `default_pass_scheme`. You will
have to settle for the `SHA-512` scheme instead.
-{% highlight ini %}
+```ini
driver = pgsql
connect = host=127.1 dbname=mail user=postfix password=incredibly-secret!
default_pass_scheme = BLF-CRYPT
@@ -210,7 +215,7 @@ user_query = \
125 AS gid \
FROM users \
WHERE local='%n' AND domain='%d';
-{% endhighlight %}
+```
## Conclusion
After this part, you should be left with a functioning email server that
@@ -220,4 +225,4 @@ in the next part, we will deal with practices that "authenticate" your emails
as legit messages. Be sure to read up on it!
[dovecot]: http://dovecot.org/
-[home]: {{ "/" | prepend: site.baseurl }}
+[home]: /
diff --git a/src/_posts/2016-10-31-freebsd-mailserver-part-4-message-authentication.md b/content/posts/2016/2016-10-31-freebsd-mailserver-part-4-message-authentication.md
index e5cee0e..62a2799 100644
--- a/src/_posts/2016-10-31-freebsd-mailserver-part-4-message-authentication.md
+++ b/content/posts/2016/2016-10-31-freebsd-mailserver-part-4-message-authentication.md
@@ -1,8 +1,12 @@
---
-title: "FreeBSD email server - Part 4: Message authentication"
date: 2016-10-31 20:00:38
-tags: Tutorial FreeBSD Email DKIM SPF
-layout: post
+title: "FreeBSD email server - Part 4: Message authentication"
+tags:
+- Tutorial
+- FreeBSD
+- Email
+- DKIM
+- SPF
---
Welcome to another part in the FreeBSD email server series. This time, we are
@@ -17,14 +21,14 @@ We will do so using three of the most common practices: [SPF][spf],
### Installation
The tools for DKIM are easily installed using `pkg`.
-{% highlight sh %}
+```
pkg install opendkim
-{% endhighlight %}
+```
### Configuration
Write the following configuration into `/usr/local/etc/mail/opendkim.conf`.
-{% highlight apache %}
+```apache
# logging
Syslog yes
@@ -54,28 +58,28 @@ Socket inet:8891@localhost
Domain domain.tld.privkey
KeyFile /usr/local/etc/opendkim/domain.tld
Selector mail
-{% endhighlight %}
+```
#### Postfix
Postfix needs to be instructed to sign the messages with a DKIM header using
the opendkim service. You can do so by inserting the following configuration
block somewhere around the end of `/usr/local/etc/postfix/main.cf`.
-{% highlight ini %}
+```ini
# milters
milter_protocol = 2
milter_default_action = reject
smtpd_milters =
inet:localhost:8891
-{% endhighlight %}
+```
#### System service
OpenDKIM runs as a system service. As such, you will have to enable this
service in rcinit. This is a simple step, achieved with the given command.
-{% highlight sh %}
+```
echo 'milteropendkim_enable="YES"' >> /etc/rc.conf.local
-{% endhighlight %}
+```
Do not forget to actually start the service when you are done with the
tutorial!
@@ -85,16 +89,16 @@ In order to use DKIM, you will need to generate some keys to sign the messages
with. You cannot use your Let's Encrypt SSL keys for this. First, create a
directory to house your domain's keys.
-{% highlight sh %}
+```
mkdir -p /usr/local/etc/opendkim/keys/domain.tld
chown -R postfix:wheel $_
-{% endhighlight %}
+```
Next up, generate your first key.
-{% highlight sh %}
+```
opendkim-genkey -D /usr/local/etc/opendkim/keys -b 4096 -r -s $(date +%Y%m%d) -d domain.tld
-{% endhighlight %}
+```
I tend to use the current date for the key names so I can easily sort them by
the most recent one.
@@ -103,11 +107,11 @@ Afterwards, you will have to add a line to two separate files to instruct DKIM
to use this key for a certain domain when signing mail. These are fairly
straightforward and can be done using a simple `echo` as well.
-{% highlight sh %}
+```
echo '*@domain.tld domain.tld' >> /usr/local/etc/opendkim/signing.table
echo "domain.tld domain.tld:$(date +%Y%m%d):/usr/local/etc/opendkim/keys/domain.tld/$(date +%Y%m%d).private" \
>> /usr/local/etc/opendkim/key.table
-{% endhighlight %}
+```
### Adding the DNS records
You may have already noticed that `opendkim-genkey` also creates a `.txt` file
diff --git a/src/_posts/2016-10-31-freebsd-mailserver-part-5-filtering-mail.md b/content/posts/2016/2016-10-31-freebsd-mailserver-part-5-filtering-mail.md
index d1797eb..07f8e21 100644
--- a/src/_posts/2016-10-31-freebsd-mailserver-part-5-filtering-mail.md
+++ b/content/posts/2016/2016-10-31-freebsd-mailserver-part-5-filtering-mail.md
@@ -1,8 +1,13 @@
---
-title: "FreeBSD email server - Part 5: Filtering mail"
date: 2016-10-31 20:02:19
-tags: Tutorial FreeBSD Email Postfix SpamAssassin Pigeonhole
-layout: post
+title: "FreeBSD email server - Part 5: Filtering mail"
+tags:
+- Tutorial
+- FreeBSD
+- Email
+- Postfix
+- SpamAssassin
+- Pigeonhole
---
Being able to send mail and not be flagged as spam is pretty awesome on itself.
@@ -21,9 +26,9 @@ instead of the inbox.
Both packages are available through FreeBSD's `pkg` utility. Install them as
such.
-{% highlight sh %}
+```
pkg install dovecot-pigeonhole spamassassin
-{% endhighlight %}
+```
## SpamAssassin
### Enabling the service
@@ -32,19 +37,19 @@ to Dovecot, and Dovecot will handle this one. SpamAssassin requires you to
configure the service as well. You can enable it and set sane configuration to
it with the following two commands.
-{% highlight sh %}
+```
echo 'spamd_enable="YES"' >> /etc/rc.conf.local
echo 'spamd_flags="-u spamd -H /srv/mail"' >> /etc/rc.conf.local
-{% endhighlight %}
+```
### Acquiring default spam rules
SpamAssassin has to "learn" what counts as *spam* and what counts as *ham*. To
fetch these rules, you should execute the updates for SpamAssassin with the
following command.
-{% highlight sh %}
+```
sa-update
-{% endhighlight %}
+```
You most likely want to run this once every while, so it is advised to setup a
cronjob for this purpose.
@@ -60,11 +65,11 @@ There's not much to include to the already existing Postfix configuration to
enable SpamAssassin to do its job. Just open `/usr/local/etc/postfix/master.cf`
and append the block given below.
-{% highlight ini %}
+```ini
spamassassin unix - n n - - pipe
user=spamd argv=/usr/local/bin/spamc
-f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}
-{% endhighlight %}
+```
## Pigeonhole
Pigeonhole is an implementation of Sieve for Dovecot. It deals with filtering
@@ -73,7 +78,7 @@ named `sieve`. This file is generally saved at
`/srv/mail/domain.tld/user/sieve`. A default file to filter spam out is the
following example.
-```
+```sieve
require [
"fileinto",
"mailbox"
@@ -98,21 +103,21 @@ following files and add the contents described.
### conf.d/20-lmtp.conf
This will enable Pigeonhole in Dovecot.
-{% highlight ini %}
+```ini
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
-{% endhighlight %}
+```
### conf.d/90-plugin.conf
This configures Pigeonhole to look for a file named `sieve` in the mailbox
homedir, and execute that when delivering mail.
-{% highlight ini %}
+```ini
plugin {
sieve = /srv/mail/%d/%n/sieve
}
-{% endhighlight %}
+```
## Conclusion
Spam is a pain, especially if you get a lot of it. The configuration added in
@@ -122,6 +127,6 @@ contact me via any of the methods detailed on [my home page][home].
Thanks for reading along, and enjoy your very own email server!
-[home]: {{ "/" | prepend: site.baseurl }}
+[home]: /
[pigeonhole]: http://pigeonhole.dovecot.org/
[spamassassin]: https://spamassassin.apache.org/
diff --git a/src/_posts/2016-11-24-freebsd-mailserver-calendars-and-contacts.md b/content/posts/2016/2016-11-24-freebsd-mailserver-calendars-and-contacts.md
index 0e7d953..b39120f 100644
--- a/src/_posts/2016-11-24-freebsd-mailserver-calendars-and-contacts.md
+++ b/content/posts/2016/2016-11-24-freebsd-mailserver-calendars-and-contacts.md
@@ -1,8 +1,12 @@
---
-title: "FreeBSD email server - Part +: Calendars and contacts"
date: 2016-11-24 08:26:09
-tags: Tutorial FreeBSD Email CalDAV CardDAV
-layout: post
+title: "FreeBSD email server - Part +: Calendars and contacts"
+tags:
+- Tutorial
+- FreeBSD
+- Email
+- CalDAV
+- CardDAV
---
This guide is an addition to the [FreeBSD email server series][tutorial-email].
@@ -12,9 +16,9 @@ party email provider to their own solution. It does build upon the completed
series, so be sure to work through that before starting on this.
## Install required packages
-{% highlight sh %}
+```
pkg install py27-radicale
-{% endhighlight %}
+```
## Configure Radicale
### /usr/local/etc/radicale/config
@@ -25,7 +29,7 @@ The server is binding to `localhost` only. This way it is not accessible on
`:5232` from outside the server. Outside access will be provided through an
nginx reverse proxy instead.
-{% highlight ini %}
+```ini
hosts = 127.1:5232
daemon = True
@@ -35,33 +39,33 @@ base_prefix = /
can_skip_base_prefix = False
realm = Radicale - Password required
-{% endhighlight %}
+```
#### [encoding]
-{% highlight ini %}
+```ini
request = utf-8
stock = utf-8
-{% endhighlight %}
+```
#### [auth]
-{% highlight ini %}
+```ini
type = IMAP
imap_hostname = localhost
imap_port = 143
imap_ssl = False
-{% endhighlight %}
+```
#### [storage]
-{% highlight ini %}
+```ini
type = filesystem
filesystem_folder = /usr/local/share/radicale
-{% endhighlight %}
+```
#### [logging]
-{% highlight ini %}
+```ini
config = /usr/local/etc/radicale/logging
-{% endhighlight %}
+```
### /usr/local/etc/radicale/logging
This file is fine on the defaults in FreeBSD 11. This saves you from
@@ -75,7 +79,7 @@ option is needed again. Bind it to `localhost`, so it can only be used
internally. In `/usr/local/etc/dovecont/conf.d/10-master.conf`, enable the
`imap` port again:
-```
+```ini
...
service imap-login {
inet_listener imap {
@@ -99,7 +103,7 @@ Assuming you have taken the crash-course in setting up the nginx webserver, you
can attain a reverse proxy using the following config block. Note that this block
only does HTTPS, as I use HTTP only to redirect to HTTPS.
-{% highlight nginx %}
+```nginx
# static HTTPS
server {
# listeners
@@ -120,18 +124,18 @@ server {
proxy_pass http://127.1:5232;
}
}
-{% endhighlight %}
+```
## Enable the service at startup
-{% highlight sh %}
+```
echo 'radicale_enable="YES"' >> /etc/rc.conf.local
-{% endhighlight %}
+```
## Start the server
-{% highlight sh %}
+```
service radicale start
-{% endhighlight %}
+```
[nginx]: https://www.nginx.com/
-[tutorial-email]: {{ "/post/2016/10/31/freebsd-mailserver-part-1-preparations/" | prepend: site.baseurl }}
-[tutorial-webserver]: {{ "/post/2016/10/25/setup-nginx-with-lets-encrypt-ssl/" | prepend: site.baseurl }}
+[tutorial-email]: /post/2016/10/31/freebsd-mailserver-part-1-preparations/
+[tutorial-webserver]: /post/2016/10/25/setup-nginx-with-lets-encrypt-ssl/
diff --git a/content/posts/2016/_index.md b/content/posts/2016/_index.md
new file mode 100644
index 0000000..74b1787
--- /dev/null
+++ b/content/posts/2016/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2016
+---
diff --git a/src/_posts/2017-09-14-how-to-git.md b/content/posts/2017/2017-09-14-how-to-git.md
index b16a6ae..39b884e 100644
--- a/src/_posts/2017-09-14-how-to-git.md
+++ b/content/posts/2017/2017-09-14-how-to-git.md
@@ -1,10 +1,9 @@
---
+date: 2017-09-14
title: "How to: git"
-date: 2017-09-14 19:46:34
-tags: Tutorial Git
-layout: post
-authors:
- - ["Patrick Spek", "http://tyil.work"]
+tags:
+- Tutorial
+- Git
---
This guide will explain how to use `git` more efficiently, and why you should
@@ -27,21 +26,21 @@ As such, **always** use a fork. If the service does not have a fancy button for
you to click, you can still fork manually. Simply clone their repository as
usual, set a new remote and push it there:
-{% highlight sh %}
+```
git clone git@domain.tld:them/repo.git
cd repo
git remote rename origin upstream
git remote add origin git@domain.tld:you/repo.git
git push origin master
-{% endhighlight %}
+```
The default naming convention uses `upstream` for the base of your fork, and
`origin` for your remote version of the repository. If a merge request is
accepted on the original repo, you can apply it to your fork using
-{% highlight sh %}
+```
git pull upstream master
-{% endhighlight %}
+```
## Branching
Branching is the art of using separate branches to introduce new code into your
@@ -159,13 +158,13 @@ commit contains a correct signature.
To enable signing of all commits, add the following configuration to your
`~/.gitconfig`:
-{% highlight ini %}
+```ini
[commit]
gpgsign = true
[user]
signingkey = 9ACFE193FFBC1F50
-{% endhighlight %}
+```
Ofcourse, you will have to update the value of the `signingkey` to match
the key you want to sign your commits with.
@@ -181,4 +180,3 @@ after finishing it, contact me via any method listed on [my home page][home].
[gogs]: https://gogs.io
[home]: https://tyil.work
[so-git-branch]: https://softwareengineering.stackexchange.com/questions/335654/git-what-issues-arise-from-working-directly-on-master
-
diff --git a/src/_posts/2017-09-28-perl6-creating-a-background-service.adoc b/content/posts/2017/2017-09-28-perl6-creating-a-background-service.md
index 4cc759d..4f94bb6 100644
--- a/src/_posts/2017-09-28-perl6-creating-a-background-service.adoc
+++ b/content/posts/2017/2017-09-28-perl6-creating-a-background-service.md
@@ -1,62 +1,60 @@
---
-date: 2017-09-28 15:11:43
-tags: Tutorial Perl6 Programming Raku
-description: >
- I've recently made some progress on Shinrin, a centralized logging system in
- Perl 6. This has to run as service, which means that for most service
- managers it has to be able to run in the background.
+date: 2017-09-28
+title: Perl 6 - Creating a background service
+tags:
+- Tutorial
+- Perl6
+- Programming
+- Raku
---
-= Perl 6 - Creating a background service
-:toc: preamble
I've recently made some progress on
-https://github.com/scriptkitties/perl6-Shinrin[Shinrin], a centralized logging
+[Shinrin](https://github.com/scriptkitties/perl6-Shinrin) a centralized logging
system in Perl 6. This has to run as service, which means that for most service
managers it has to be able to run in the background.
-[NOTE]
-====
+{{< admonition title="Note" >}}
If you just want to get to the solution and don't care for the details, just
-head straight to link:#the-final-solution[the full script].
-====
+head straight to [the full script](#the-final-solution).
+{{< / admonition >}}
+
+## It's not possible!
-== It's not possible!
After a lot of trying and talking with the folks at
-irc://chat.freenode.net:6697/#perl6[#perl6] I was told that it is not possible
+[#perl6](irc://chat.freenode.net:6697/#perl6) I was told that it is not possible
to do this in pure Perl 6, explained by people with more knowledge than I have
on the internals:
-[quote, jnthn]
-____
+{{< quote attribution="jnthn" >}}
(jnthn suspects fork + multi-threaded VM = pain) Since fork only clones one
thread - the one that called it. So suddenly you've got an instance of the VM
missing most of its threads.
-____
+{{< / quote >}}
-[quote, geekosaur]
-____
+{{< quote attribution="geekosaur" >}}
The most common failure mode is that some thread is holding e.g. a mutex (or a
userspace lock) during the fork. The thread goes away but the lock is process
level and remains, with nothing around to know to unlock it. So then things
work until something else needs that lock and suddenly you deadlock.
-____
+{{< / quote >}}
+
+Not much later, `jnthn` [pushed a
+commit](https://github.com/perl6/doc/commit/8f9443c3ac) to update the docs to
+clarify that a `fork` call through `NativeCall` will probably not give the
+result you were hoping for.
-Not much later, `jnthn` https://github.com/perl6/doc/commit/8f9443c3ac[pushed a
-commit] to update the docs to clarify that a `fork` call through `NativeCall`
-will probably not give the result you were hoping for.
+## Or is it?
-== Or is it?
Luckily, the same people were able to think up of a work-around, which can be
made in POSIX sh, so it's usable on any decent OS. The workaround is to let a
little shell script fork into the background, and let that run the Perl
application.
-=== A first example
+### A first example
This is fairly simple to create, as in this example to launch `shinrind` in the
background:
-[source,sh]
-----
+```sh
#! /usr/bin/env sh
main()
@@ -65,19 +63,21 @@ main()
}
main "$@" &
-----
+```
This works just fine if the working directory is correct. This means you need
to be in the parent directory to `lib` and `bin` of the program to make it
work.
-== Improving the forking script
+## Improving the forking script
+
While that short script works fine to show a proof of concept, in order to make
it viable for real-world scenarios, it can use some improvements. After all, it
would be annoying if you'd have to `cd` to a specific directory any time you
want to start your application.
-=== Ensure you are in the directory you should be in
+### Ensure you are in the directory you should be in
+
So for starters, let's make sure that you can run it from anywhere on your
system. For this, you should set the working directory for the script, so you
don't have to do it manually. Because the script runs in its own subshell, the
@@ -86,10 +86,9 @@ shell you're working from remains unaffected.
A POSIX compliant way to get the directory the script is stored in is as
follows:
-[source,sh]
-----
+```sh
DIR=$(CDPATH="" cd -- "$(dirname -- "$0")" && pwd)
-----
+```
This will set `$DIR` to the path of the directory the shell script is stored
in. You can simply `cd` to that and be assured you're in the right directory.
@@ -99,20 +98,19 @@ of your project repository. So you should actually be in the parent of the
directory holding your script. Furthermore, you should check the `cd` command
executed correctly, just to be safe.
-[source,sh]
-----
+```sh
cd -- "${DIR}/.." || exit
-----
+```
+
+### Disable `STDOUT` and `STDERR`
-=== Disable `STDOUT` and `STDERR`
A started service should not be polluting your interactive shell, so you should
disable (or otherwise redirect) `STDOUT` and `STDERR`. This is done in the
shell using a small bit of code behind whatever you want to redirect:
-[source,sh]
-----
+```sh
> /dev/null 2>&1
-----
+```
This will set `STDOUT` to `/dev/null`, and set `STDERR` to the same stream as
`STDOUT`, which in effect will make all output go to `/dev/null`. If you want
@@ -123,27 +121,27 @@ use a `>>` instead of a single `>` at the start.
If you want to log errors and output in different files, you can use the
following:
-[source,sh]
-----
+```sh
> /var/log/service.log 2> /var/log/service.err
-----
+```
This will put standard output in `/var/log/service.log` and errors in
`/var/log/service.err`.
-=== Fork just the Perl 6 program
+### Fork just the Perl 6 program
+
In the initial example, I put the `&` behind the `main` call, at the bottom of
the script. While this works just fine for most simple usage, if you want to do
additional chores, like creating a pidfile after starting the Perl 6 program,
you're out of luck. If you were to only fork the Perl 6 application, you could
handle some other cases in the shell script.
-== The final solution
+### The final solution
+
For those eager to just get going with this, here is the complete example
script to just fork your Perl program into the background:
-[source,sh]
-----
+```sh
#! /usr/bin/env sh
readonly DIR=$(CDPATH="" cd -- "$(dirname -- "$0")" && pwd)
@@ -156,4 +154,4 @@ main()
}
main "$@"
-----
+```
diff --git a/src/_posts/2017-11-01-hacktoberfest-2017.adoc b/content/posts/2017/2017-11-01-hacktoberfest-2017.md
index 67c7746..015f341 100644
--- a/src/_posts/2017-11-01-hacktoberfest-2017.adoc
+++ b/content/posts/2017/2017-11-01-hacktoberfest-2017.md
@@ -1,43 +1,44 @@
---
-date: 2017-11-01 12:37:53
-tags: FreeSoftware Github Hacktoberfest Contributions
-description: >
- This year I actively participated in the Hacktoberfest event, which is 'a
- month-long celebration of open source software'. Ironic, given that the
- companies organising it don't have their own software stack open source.
- Nevertheless, I did contribute to free software, and this article lists these
- contributions.
+title: Hacktoberfest 2017
+date: 2017-11-01
+tags:
+- Contributions
+- FreeSoftware
+- Github
+- Hacktoberfest
---
-= Hacktoberfest 2017
-:toc: preamble
This year I actively participated in the Hacktoberfest event, which is "a
month-long celebration of open source software". Ironic, given that the
companies organising it don't have their own software stack open source.
-I've found some issues to solve in https://perl6.org/[Perl 6] projects, and
+I've found some issues to solve in [Perl 6](https://perl6.org/) projects, and
that lead to trying to solve issues in some other projects, and eventually I
got more PRs out than there are days in the month. It did go at the cost of
some sleep, but in the end it seems worth it. In this article, I'll give a
small overview of all those PRs, in no particular order.
-== Projects contributed to
-=== Funtoo
-==== funtoo/boot-update
+## Projects contributed to
+
+### Funtoo
+
+#### funtoo/boot-update
+
- https://github.com/funtoo/boot-update/pull/14
-When reinstalling my server to try out https://docker.com[Docker], I noticed an
-error in the output of the `boot-update` utility, a tool from
-https://www.funtoo.org/Welcome[Funtoo] to make installing and configuring the
+When reinstalling my server to try out [Docker](https://docker.com), I noticed
+an error in the output of the `boot-update` utility, a tool from
+[Funtoo](https://www.funtoo.org/Welcome) to make installing and configuring the
bootloader easier. The error itself was a small type of a `-` which had to be a
`_`.
-==== scriptkitties/overlay
+#### scriptkitties/overlay
+
- https://github.com/scriptkitties/overlay/pull/14
- https://github.com/scriptkitties/overlay/pull/15
- https://github.com/scriptkitties/overlay/pull/16
-This is the overlay of the https://scriptkitties.church[Scriptkitties]
+This is the overlay of the [Scriptkitties](https://scriptkitties.church)
community. It's got some additional software released under a free license that
is not available in the main portage repository. Most of the packages in here
are of software made by the Scriptkitties community.
@@ -47,40 +48,46 @@ documentation. The Travis builds should also no longer throw errors, so those
can be used again to ensure the overlay is meeting quality standards. One
package has also been updated to be at it's latest version again.
-=== Perl 6
-==== moznion/p6-HTML-Escape
+### Perl 6
+
+#### moznion/p6-HTML-Escape
+
- https://github.com/moznion/p6-HTML-Escape/pull/1
On this repository, I added a subroutine to also handle unescaping HTML special
characters. Sadly, the owner of this repository has shown no sign of life, and
the PR remains open.
-==== rakudo/rakudo
+#### rakudo/rakudo
+
- https://github.com/rakudo/rakudo/pull/1180
This is a rather small issue, but I noticed it when compiling Perl 6 with
-https://github.com/tadzik/rakudobrew[Rakudobrew] and it annoyed me.
-http://zoffix.com/[Zoffix] was a great help in getting me started on this one,
+[Rakudobrew](https://github.com/tadzik/rakudobrew) and it annoyed me.
+[Zoffix](http://zoffix.com/) was a great help in getting me started on this one,
and in general with many other Perl related contributions as well.
-==== scriptkitties/perl6-IRC-Client-Plugin-Github
+#### scriptkitties/perl6-IRC-Client-Plugin-Github
+
- https://github.com/scriptkitties/perl6-IRC-Client-Plugin-Github/pull/2
A neat feature for the Github notification system, HMAC adds a header that can
be used to verify the body of the request, and can be used to verify the other
end of the connection knows the right "secret". Inspired by a Perl 6 bot that
already did this, I made a PR to make this a proper
-https://github.com/zoffixznet/perl6-IRC-Client[IRC::Client] plugin. It is still
-being tested in https://github.com/scriptkitties/musashi[musashi].
+[`IRC::Client`](https://github.com/zoffixznet/perl6-IRC-Client) plugin. It is still
+being tested in [musashi](https://github.com/scriptkitties/musashi).
+
+#### perl6/roast
-==== perl6/roast
- https://github.com/perl6/roast/pull/342
Roast is the test suite for Perl 6. There was an open issue for the IO::File
tests, which needed expansion. As my first contribution during a Perl 6
squashaton, I expanded these tests to fix the issue that was open for it.
-==== vim-perl/vim-perl6
+#### vim-perl/vim-perl6
+
- https://github.com/vim-perl/vim-perl6/pull/9
- https://github.com/vim-perl/vim-perl6/pull/10
@@ -90,7 +97,8 @@ fork off and update the reference on the Perl documentation to my fork.
Nonetheless, it's sorted out, and the abbreviations for unicode operators
have been merged in!
-==== timo/json_fast
+#### timo/json_fast
+
- https://github.com/timo/json_fast/pull/32
`JSON::Fast` is the de-facto standard for dealing with JSON data in Perl 6 it
@@ -102,15 +110,17 @@ git diffs a lot cleaner.
Sadly, timo has not merged the PR yet, so I can't properly depend on it in
`App::Cpan6`.
-==== scriptkitties/perl6-SemVer
+#### scriptkitties/perl6-SemVer
+
- https://github.com/scriptkitties/perl6-SemVer/pull/1
This is one of the new projects I started. It is intended to be used in
-`App::Cpan6`, since that uses https://semver.org[Semantic Versioning] for all
+`App::Cpan6`, since that uses [Semantic Versioning](https://semver.org) for all
modules it works with. This module defines a class that can interpret a SemVer
notation, and exposes methods to bump any part of the version.
-==== perl6/doc
+#### perl6/doc
+
- https://github.com/perl6/doc/pull/1614
This has been one of the more annoying PRs to work on, as the current `zef`
@@ -124,16 +134,18 @@ itself, mainly the `META6.json` specification, and getting `zef` to play nice
with this spec. If anyone else is interested in helping me out on this, do
message me on IRC!
-==== perl6/perl6.org
+#### perl6/perl6.org
+
- https://github.com/perl6/perl6.org/pull/86
- https://github.com/perl6/perl6.org/pull/87
-There were some open issues for the https://perl6.org[perl6.org] website, and I
-decided to take a look at some and try to fix them. This resulted in NeoVim
+There were some open issues for the [perl6.org](https://perl6.org) website, and
+I decided to take a look at some and try to fix them. This resulted in NeoVim
being added to the list of recommended editors for Perl 6, and the list of IRC
bots being updated to include all bots in use right now.
-==== scriptkitties/p6-MPD-Client
+#### scriptkitties/p6-MPD-Client
+
- https://github.com/scriptkitties/p6-MPD-Client/pull/1
- https://github.com/scriptkitties/p6-MPD-Client/pull/2
@@ -141,7 +153,8 @@ As I was making `App::MPD::AutoQueue` and `App::MPD::Notify`, I found some
issues in `MPD::Client`. I fixed those to get my two new projects working
nicely.
-==== melezhik/sparrowdo
+#### melezhik/sparrowdo
+
- https://github.com/melezhik/sparrowdo/pull/15
- https://github.com/melezhik/sparrowdo/pull/18
@@ -153,7 +166,8 @@ In addition, I also rewrote the testing script for Travis, which enables
paralel builds of the tests. This has nearly halved the time required for
running the full test suite.
-==== perl6/ecosystem
+#### perl6/ecosystem
+
- https://github.com/perl6/ecosystem/pull/371
- https://github.com/perl6/ecosystem/pull/372
- https://github.com/perl6/ecosystem/pull/374
@@ -161,7 +175,8 @@ running the full test suite.
These PRs added a module, and removed that one and more later on, since I got a
PAUSE ID and uploaded my modules to CPAN.
-==== scriptkitties/perl6-App-Cpan6
+#### scriptkitties/perl6-App-Cpan6
+
- https://github.com/scriptkitties/perl6-App-Cpan6/pull/1
- https://github.com/scriptkitties/perl6-App-Cpan6/pull/2
- https://github.com/scriptkitties/perl6-App-Cpan6/pull/3
@@ -180,7 +195,8 @@ If everything works out and I learn enough of the module installation process,
I might consider letting this deal with the installation and updating of
modules as well.
-== In retrospect
+## In retrospect
+
The Hacktoberfest has been an interesting month for me. I've gotten to
contribute to a project I have come to love a lot, Perl 6. I've also made some
new friends with similar goals. Sadly I can't put in this much time every month
diff --git a/src/_posts/2017-11-16-perl6-setting-up-a-raspberry-perl.adoc b/content/posts/2017/2017-11-16-perl6-setting-up-a-raspberry-perl.md
index 7ea72fa..eb42853 100644
--- a/src/_posts/2017-11-16-perl6-setting-up-a-raspberry-perl.adoc
+++ b/content/posts/2017/2017-11-16-perl6-setting-up-a-raspberry-perl.md
@@ -1,22 +1,19 @@
---
-date: 2017-11-16 11:58:40
-tags: Tutorial Perl6 RaspberryPi Raku
-description: >
- In this tutorial I'll get you through setting up a Raspberry Pi with Perl 6.
- I am using a Raspberry Pi 3 myself, but other versions should work fine too.
- However, older versions are slower, so it might take a bit longer to install
- completely.
+date: 2017-11-16
+title: "Setting up a Raspberry Perl"
+tags:
+- Tutorial
+- Perl6
+- RaspberryPi
+- Raku
---
-= Perl 6 - Setting up a Raspberry Perl
-:toc: preamble
In this tutorial I'll get you through setting up a Raspberry Pi with
-https://perl6.org/[Perl 6]. I am using a Raspberry Pi 3 myself, but other
+[Perl 6](https://perl6.org/). I am using a Raspberry Pi 3 myself, but other
versions should work fine too. However, older versions are slower, so it might
take a bit longer to install completely.
-[NOTE]
-====
+{{< admonition title="Note" >}}
For those who have never had a Raspberry Pi before, you will need
the following:
@@ -25,26 +22,26 @@ the following:
- SD card of at least 4gb, but I would advise at least 8gb
- Monitor with HDMI cable
- Keyboard
-====
+{{< / admonition >}}
Perl 6 will be installed using
-https://github.com/tadzik/rakudobrew[Rakudobrew], which I'll also be using to
-get https://github.com/ugexe/zef[zef] installed. Zef is the recommended module
+[Rakudowbrew](https://github.com/tadzik/rakudobrew), which I'll also be using to
+get [zef](https://github.com/ugexe/zef) installed. Zef is the recommended module
manager for Perl 6.
-== Setting up Raspbian
+## Setting up Raspbian
The first step is getting the OS set up. To keep this tutorial simple, I will
-stick to https://www.raspbian.org/[Raspbian], but if you feel confident in your
-skills you can use any other distribution or OS. Perl 6 installs the same on
-all UNIX(-like) operating systems.
+stick to [Raspbian](https://www.raspbian.org/), but if you feel confident in
+your skills you can use any other distribution or OS. Perl 6 installs the same
+on all UNIX(-like) operating systems.
-=== Get the image
+### Get the image
-First, https://www.Raspberrypi.org/downloads/raspbian/[download the Raspbian
-image from the Raspberry Pi download page]. I chose the `LITE` version, but if
-you prefer having a graphical desktop you can go for the `DESKTOP` version
-instead.
+First, [download the Raspbian image from the Raspberry Pi download
+page](https://www.Raspberrypi.org/downloads/raspbian/). I chose the `LITE`
+version, but if you prefer having a graphical desktop you can go for the
+`DESKTOP` version instead.
At the time of writing, this means I got the
`2017-09-07-raspbian-stretch-lite.zip`. If you want to verify you got the
@@ -55,26 +52,20 @@ To get the checksum of the file you downloaded, use `sha256sum` as follows:
NOTE: Lines prepended with a `$` are to be ran as your normal user, whereas
lines with a `#` are ment to be ran as "super user". This can be done by using
a privilege escalation program, such as
-https://www.linux.com/blog/how-use-sudo-and-su-commands-linux-introduction[`sudo`].
+[`sudo`](https://www.linux.com/blog/how-use-sudo-and-su-commands-linux-introduction).
-[source]
-----
-$ sha256sum 2017-09-07-raspbian-stretch-lite.zip
-----
+ $ sha256sum 2017-09-07-raspbian-stretch-lite.zip
If the checksum matches the one noted below the download button you used, it
should be fine, and you can continue with extracting the image from the zip
using `unzip`:
-[source]
-----
-$ unzip 2017-09-07-raspbian-stretch-lite.zip
-----
+ $ unzip 2017-09-07-raspbian-stretch-lite.zip
This will result in a similarly named file, but with a `.img` extension instead
of `.zip`. This is the image that you can write to the SD card.
-=== Write the image to the SD card
+### Write the image to the SD card
This step is pretty easy, but typos here can be disastrous for the system
you're using to write to the SD card.
@@ -87,24 +78,21 @@ means the device file resides at `/dev/sdb`.
Now, to actually write the image, I'll use `dd` since this is everyone's
favourite tool, it seems. If you feel adventurous enough to try out something
different, feel free to read up on
-https://www.vidarholen.net/contents/blog/?p=479[Useless Use of dd].
+[Useless Use of `dd`](https://www.vidarholen.net/contents/blog/?p=479).
Make sure to make the `if` argument point to the correct path with your
extracted raspbian image, and `of` to point to the correct device as identified
earlier. In order to be allowed to run this command, you must be root, which
can be achieved by using `sudo` or `doas` again.
-[source]
-----
-# dd bs=4M status=progress if=/path/to/2017-09-07-raspbian-stretch-lite.img of=/dev/sdb
-$ sync
-----
+ # dd bs=4M status=progress if=/path/to/2017-09-07-raspbian-stretch-lite.img of=/dev/sdb
+ $ sync
Afterwards, plug it into your Raspberry Pi and attach all cables you might
need. Think of stuff like a keyboard, mouse, monitor, internet, power. Do power
last, as the Raspberry Pi will start immediatly once it receives power.
-=== First boot
+### First boot
The Raspberry Pi should start booting the moment you supply it with power. If
you attach the HDMI after the power, it's possible you won't have display
@@ -115,7 +103,7 @@ You'll see some text scrolling by, up to a point where it asks you for a
default password is `Raspberry`. You are strongly advised to change the
password upon login, which can be done in the next step.
-=== Configuration
+### Configuration
The Raspberry Pi comes with its own configuration tool, `raspi-config`. Run
this with `sudo` prepended in front of it so you gain the right privileges. I
@@ -131,18 +119,15 @@ are satisfied, go back to the main menu and choose `Finish`. It will ask to
reboot, which you should accept. This will apply all the new configurations you
just made.
-=== Updating and installing additional packages
+### Updating and installing additional packages
It's rare for the system to be completely up to date after installing the image
on the SD card. Additionally, you also need some extra packages in order to get
rakudobrew, and to install Perl 6 itself. For this, we use the package manager
bundled with raspbian, `apt`:
-[source]
-----
-# apt update
-# apt upgrade
-----
+ # apt update
+ # apt upgrade
This will update the package lists, and then upgrade all outdated packages to
their newest versions. You should do this at least once a week to make sure
@@ -151,22 +136,19 @@ your system stays up to date.
Once the upgrades are finished, you can install some new packages which are
needed later on in this tutorial:
-[source]
-----
-# apt install git build-essential
-----
+ # apt install git build-essential
`git` is required to get the rakudobrew repository and is also used by
rakudobrew itself to get the sources needed to build Perl 6 and to install zef.
The `build-essential` package comes with all sorts of tools to build software,
which is required to build Perl 6.
-== Installing Perl 6
+## Installing Perl 6
Now, we've got a working Raspberry Pi installation. We can start doing things
with it, such as playing around with Perl 6.
-=== Setting up Rakudobrew
+### Setting up Rakudobrew
Rakudobrew is a nice tool to manage Perl 6 installations on your system. It can
also install `zef` for you, so you don't have to deal with this manually. This
@@ -177,47 +159,35 @@ preferred setup more closely.
Clone the repository to your system, and add it to your `$PATH` to be able to
use the scripts bundled with it:
-[source]
-----
-$ mkdir -p ~/.local/var
-$ git clone https://github.com/tadzik/rakudobrew.git ~/.local/var/rakudobrew
-$ export PATH=${HOME}/.local/var/rakudobrew/bin:$PATH
-$ hash -r
-----
+ $ mkdir -p ~/.local/var
+ $ git clone https://github.com/tadzik/rakudobrew.git ~/.local/var/rakudobrew
+ $ export PATH=${HOME}/.local/var/rakudobrew/bin:$PATH
+ $ hash -r
The `hash -r` call will rehash your PATH, so you can tab-complete `rakudobrew`.
Next, initialize rakudobrew:
-[source]
-----
-$ rakudobrew init
-----
+ $ rakudobrew init
This will give you a notification to automatically load rakudobrew next time.
It is advised you follow that message, so you won't have to do it manually each
time you log in to the system.
-=== Installing Perl 6 with MoarVM backend
+### Installing Perl 6 with MoarVM backend
Now that rakudobrew is installed and available to use, it's time to make use of
it to install Perl 6.
-[source]
-----
-$ rakudobrew build moar
-----
+ $ rakudobrew build moar
-=== Installing zef, the module manager
+### Installing zef, the module manager
Getting zef to work isn't much harder than installing Perl 6, but its a lot
faster. You can have rakudobrew take care of this too:
-[source]
-----
-$ rakudobrew build zef
-----
+ $ rakudobrew build zef
-== Final words
+## Final words
And that should be it, you now have a working Perl 6 installation with the zef
module manager to take care of installing and upgrading modules. Now you just
@@ -232,5 +202,5 @@ Freenode, or check out some of the Perl 6 documentation and introduction sites:
For starting projects that are easy to start with and can bring quick results,
consider making an IRC bot using
-https://github.com/zoffixznet/perl6-IRC-Client[`IRC::Client`], or a small web
-application using https://github.com/Bailador/Bailador[`Bailador`].
+[`IRC::Client`](https://github.com/zoffixznet/perl6-IRC-Client), or a small web
+application using [`Bailador`](https://github.com/Bailador/Bailador).
diff --git a/src/_posts/2017-12-17-on-cloudflare.adoc b/content/posts/2017/2017-12-17-on-cloudflare.md
index 9b831a8..f802937 100644
--- a/src/_posts/2017-12-17-on-cloudflare.adoc
+++ b/content/posts/2017/2017-12-17-on-cloudflare.md
@@ -1,33 +1,32 @@
---
-date: 2017-12-17 10:13:26
-tags: Cloudflare Security Privacy
-description: >
- Cloudflare is a threat to online security and privacy. I am not the first on
- to address this issue, and I probably will not be the last either. Sadly,
- people still seem to be very uninformed as to what issues Cloudflare actually
- solves, or introduces.
+title: On Cloudflare
+date: 2017-12-17
+tags:
+- Cloudflare
+- Security
+- Privacy
---
-= On Cloudflare
-:toc:
-== Foreword
+## Foreword
+
Cloudflare is a threat to online security and privacy. I am not the first on to
address this issue, and I probably will not be the last either. Sadly, people
still seem to be very uninformed as to what issues Cloudflare actually poses.
There also seems to be a big misconception about the benefits provided by using
-Cloudflare. I would suggest reading the
-http://cryto.net/~joepie91/blog/2016/07/14/cloudflare-we-have-a-problem/[article
-on Cloudflare by joepie91] for a more thorough look at Cloudflare.
+Cloudflare. I would suggest reading the [article on Cloudflare by
+joepie91](http://cryto.net/~joepie91/blog/2016/07/14/cloudflare-we-have-a-problem/)
+for a more thorough look at Cloudflare.
If anyone is using Cloudflare, please tell them to stop doing it. Link them to
this page or any of the articles referenced here. Cloudflare is harmful to your
visitors, and if you do not care about them, they will stop caring about you
too.
-== A literal MITM attack
+## A literal MITM attack
+
Cloudflare poses a huge risk by completely breaking the TLS/SSL chain used by
browsers by setting itself up as a
-https://en.wikipedia.org/wiki/Man-in-the-middle_attack[man in the middle].
+[man in the middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack).
Cloudflare doesn't do actual DDoS protection, they just make the request to the
origin server for you. Once they have received the data, they decrypt it and
re-encrypts it with their own certificate. This means that Cloudflare has
@@ -41,15 +40,16 @@ plain text communications between you and the origin server. This data can be
used for all kinds of purposes. It is not uncommon for the USA government to
request a massive amount of surveillance information from companies without the
companies being able to speak up about it due to a gag order. This has become
-clear once more by the
-https://whispersystems.org/bigbrother/eastern-virginia-grand-jury/[subpoena on
-Signal]. It should be clear to anyone that end-to-end encryption has to be a
-standard and implemented properly. Cloudflare goes out of its way to break this
+clear once more by the [subpoena on
+Signal](https://whispersystems.org/bigbrother/eastern-virginia-grand-jury/). It
+should be clear to anyone that end-to-end encryption has to be a standard and
+implemented properly. Cloudflare goes out of its way to break this
implementation.
-=== Cloudbleed
+### Cloudbleed
+
The danger of their MITM style of operation was shown be the
-https://en.wikipedia.org/wiki/Cloudbleed[Cloudbleed] vulnerability. It also
+[Cloudbleed](https://en.wikipedia.org/wiki/Cloudbleed) vulnerability. It also
shows that they make use of their MITM position to scan the data your site and
a visitor are exchanging. This includes private data, such as passwords.
@@ -64,7 +64,8 @@ more dangerous. Whether or not you do, the content exists in plaintext on
Cloudflare's servers, which is not what you want, if you truly care about
security.
-== Eliminating your privacy
+## Eliminating your privacy
+
If Cloudflare were to fix their MITM behavior, the privacy problem would not
be solved all of a sudden. There are more questionable practices in use by
Cloudflare.
@@ -87,7 +88,8 @@ As noted in _A literal MITM attack_, this data is still very interesting to
some parties. And do not fool yourself: meta data is still very worthwhile and
can tell a huge amount of information about a person.
-=== Forcing JavaScript
+### Forcing JavaScript
+
This issue generally does not concern many people, as most people online
nowadays use a big mainstream browser with JavaScript enabled. However, there
are still people, services and applications that do not use JavaScript. This
@@ -99,13 +101,15 @@ unavailable to people who simply do not wish to use JavaScript or people who
are currently limited to a browser with no JavaScript support.
It is also common for Cloudflare to
-http://www.tedunangst.com/flak/post/cloudflare-and-rss[Break RSS readers] by
+[break RSS readers](http://www.tedunangst.com/flak/post/cloudflare-and-rss) by
presenting them with this check. This check is often presented to common user
agents used by services and programs. Since these do not include a big
JavaScript engine, there is no way for them to pass the test.
-== False advertising
-=== DDoS protection
+## False advertising
+
+### DDoS protection
+
Cloudflare is hailed by many as a gratis DDoS protection service, and they
advertise themselves as such. However, Cloudflare does not offer DDoS
protection, they simply act as a pin cushion to soak the hit. Real DDoS
@@ -122,8 +126,9 @@ not do what it is advertised to do. If you do not go to the business plan, you w
have about the same protection as you would have without it, but with the
addition of ruining the privacy and security of your visitors.
-=== Faster page loads
-This is very well explained on
-http://cryto.net/~joepie91/blog/2016/07/14/cloudflare-we-have-a-problem/[joepie91's
-article] under the heading _But The Speed! The Speed!_. As such, I will refer
-to his article instead of repeating him here.
+### Faster page loads
+
+This is very well explained on [joepie91's
+article](http://cryto.net/~joepie91/blog/2016/07/14/cloudflare-we-have-a-problem/)
+under the heading _But The Speed! The Speed!_. As such, I will refer to his
+article instead of repeating him here.
diff --git a/src/_posts/2017-12-21-funding-yourself-as-free-software-developer.adoc b/content/posts/2017/2017-12-21-funding-yourself-as-free-software-developer.md
index de687ed..a4e73cb 100644
--- a/src/_posts/2017-12-21-funding-yourself-as-free-software-developer.adoc
+++ b/content/posts/2017/2017-12-21-funding-yourself-as-free-software-developer.md
@@ -1,15 +1,11 @@
---
+date: 2017-12-21
title: Funding Yourself As A Free Software Developer
-date: 2017-12-21 05:29:26
-tags: FreeSoftware Programming Funding
-description: >
- An overview of multiple funding platforms, with pros and cons, from the
- perspective of a free software developer. It's intent is to help others find
- a possible form of income while doing what they love, and what I consider is
- immensely important for society.
+tags:
+- FreeSoftware
+- Programming
+- Funding
---
-= Funding Yourself As A Free Software Developer
-:toc: preamble
I've been meaning to spend more time on developing free software, helping out
new users on IRC and writing more tutorials to get others started. All of these
@@ -22,13 +18,14 @@ platform and turn me on to interesting platforms I missed.
I'll be focussing on platforms allowing for recurring donations, as these are
more useful for procuring a stable income.
-== Platforms
-=== BountySource
-[WARNING]
-====
-- Requires 3rd-party link:/articles/on-cloudflare/[Cloudflare]-hosted
+## Platforms
+
+### BountySource
+
+{{< admonition title="warning" >}}
+- Requires 3rd-party [Cloudflare](/post/2017-12-17/on-cloudflare/)-hosted
JavaScript sources to function.
-====
+{{< / admonition >}}
BountySource lets people donate money towards an issue on Github your projects.
Once an issue gets fixed, you can claim the "bounty" that was on this issue.
@@ -39,18 +36,18 @@ There's also BountySource Salt, which is a recurring donation platform.
Projects or teams can use this to gain monthly income to sustain the
development of their project(s).
-Support for this platform is offered through the IRC channel
-https://kiwiirc.com/client/chat.freenode.net:+6697/#bountysource[`#bountysource`
-on Freenode].
+Support for this platform is offered through the IRC channel [`#bountysource` on
+Freenode](https://kiwiirc.com/client/chat.freenode.net:+6697/#bountysource).
The BountySource platform itself is also free software, and the source code
-for it can be found https://github.com/bountysource/core[on github].
+for it can be found [on GitHub](https://github.com/bountysource/core).
You can find BountySource at https://www.bountysource.com/.
-=== LiberaPay
+### LiberaPay
+
This service seems to be completely free as in freedom. They even
-https://github.com/liberapay/liberapay.com[publish their source on GitHub].
+[publish their source on GitHub](https://github.com/liberapay/liberapay.com).
Their own funding comes through donations on their own platform, instead of
taking a cut of each donation like most other services.
@@ -69,12 +66,12 @@ you to set reward tiers, which allow you to give certain benefits to donors.
You can find Liberapay at https://liberapay.com/.
-=== MakerSupport
-[WARNING]
-====
+### MakerSupport
+
+{{< admonition title="Warning" >}}
- The site requires a 3rd-party hosted jQuery.
- You have to solve a Google reCaptcha in order to register a new account.
-====
+{{< / admonition >}}
MakerSupport seems to be another option, aimed at content creators who might
need freedom of speech more than others. It seems to be less focused on
@@ -102,21 +99,20 @@ requests. Secondly, their error when uploading a "wrong" format is also not
very user friendly, as it won't give you any details on why it's disallowed,
nor what images are allowed instead.
-[NOTE]
-====
+{{< admonition title="Note" >}}
It seems they check the extension of the uploaded image's filename. As far as I
can tell, you're allowed to upload files that end with `.jpg` and `.png`.
-====
+{{< / admonition >}}
You can find MakerSupport at https://www.makersupport.com/.
-=== Patreon
-[WARNING]
-====
-- Requires 3rd-party link:/articles/on-cloudflare[Cloudflare]-hosted
+### Patreon
+
+{{< admonition title="Warning" >}}
+- Requires 3rd-party [Cloudflare](/post/2017/12/17/on-cloudflare/)-hosted
JavaScript sources to function.
- You have to solve a Google reCaptcha in order to register a new account.
-====
+{{< / admonition >}}
Patreon is possibly the most famous donation-based funding platform available
right now. Its popularity is a good thing, since this means there's probably
@@ -141,8 +137,10 @@ platforms.
You can find Patreon at https://www.patreon.com/home.
-=== (Dis)honorable mentions
-==== Hatreon
+### (Dis)honorable mentions
+
+#### Hatreon
+
I've included this because I found people talking about it on IRC. However, it
seems to be nothing more than a joke that's gone too far. Its main reason for
existing seems to be to get away from the political correctness found with
@@ -150,24 +148,26 @@ earlier crowdfunding platforms, yet their site is invite-only, so those who are
actually interested can't even use it. It seems that pledging is currently
disabled as well, and has been for at least 10 days.
-== But that's not all
+## But that's not all
+
Just setting up an account on a funding platform isn't enough. There's more to
keeping a healthy and happy supporter base.
-=== Spread awareness of your work
+### Spread awareness of your work
+
Whether you're writing articles or publishing new releases of projects, tell
the world you're doing whatever it is you're doing. If nobody knows about your
project, they won't be able to give any kind of appreciation for it. Use social
media outlets, public forums, mailing lists, anything! Tell them what you made,
why it's useful and how they could use it to improve their digital life.
-[WARNING]
-====
+{{< admonition title="Warning" >}}
Ofcourse, don't spam it to unrelated communication channels. This will only
backfire.
-====
+{{< / admonition >}}
+
+### Using the rewards system
-=== Using the rewards system
On the platforms that support a rewards system, make use of it. There's some
little things you can do that go a long way with your supporters. For instance,
you can offer things like stickers to donors that donate a certain amount of
@@ -180,18 +180,21 @@ to an IRC channel for you and your donors. You can use another platform for
this, but most free software enthousiasts are already on IRC, and there's few
real-time communication alternatives that they're already using.
-=== Don't stick to a single platform
+### Don't stick to a single platform
+
There's multiple platforms out there, use them! Not all of them have the same
userbase, and you can reach more people by giving them more options to work
with.
-=== Let people know you're accepting donations
+### Let people know you're accepting donations
+
If people don't know you're even accepting donations, chances are pretty high
you won't get any. Or if it's too hard to figure out how to donate to you,
people will simply not take the effort. Make sure people can easily find out
that you're accepting donations, and how to donate to you.
-=== Show what you're doing with donation money
+### Show what you're doing with donation money
+
Have a page with information about what you're using with the money. This can
be as simple as just saying you pay the rent and buy food with it. Most donors
don't mind too much what you're doing with the money they donate to you, but a
@@ -200,21 +203,22 @@ few do appreciate having this information available to them.
It can be as simple as adding a `/donate` link to your site where you explain
how to donate to you, and what you do with the donation money.
-[WARNING]
-====
+{{< admonition title="Warning" >}}
Don't let it turn into an annoying advertisement though, this will surely have
an opposite effect.
-====
+{{< / admonition >}}
+
+## Further reading
-== Further reading
There's more places to go for tips and tricks in getting funds to sustain your
free software development work. I've listed a couple of these here for those
interested.
-- https://wiki.snowdrift.coop/market-research/other-crowdfunding[snowdrift.coop wiki on crowdfunding/fundraising services]
-- https://github.com/nayafia/lemonade-stand[A handy guide to financial support for open source]
+- [snowdrift.coop wiki on crowdfunding/fundraising services](https://wiki.snowdrift.coop/market-research/other-crowdfunding)
+- [A handy guide to financial support for open source](https://github.com/nayafia/lemonade-stand)
+
+## RFC
-== RFC
I'd love to receive feedback on this, as I think being able to get donations
easily for the work free software developers put in to their projects is
important.
@@ -225,7 +229,5 @@ also like to hear from developers already using a platform, to extend this
article with more useful information on how to successfully get donors for
their work.
-If you want to contact me, do take a look at the link:/[Contact] section, and
-let me know about your experiences with funding.
-
-And if you liked this post, consider link:/support/[donating] ;)
+If you want to contact me, do take a look at the [Contact](/#contact) section,
+and let me know about your experiences with funding.
diff --git a/content/posts/2017/_index.md b/content/posts/2017/_index.md
new file mode 100644
index 0000000..141c28d
--- /dev/null
+++ b/content/posts/2017/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2017
+---
diff --git a/src/_posts/2018-02-05-why-perl6.adoc b/content/posts/2018/2018-02-05-why-perl6.md
index 8c9a299..f2a8ea3 100644
--- a/src/_posts/2018-02-05-why-perl6.adoc
+++ b/content/posts/2018/2018-02-05-why-perl6.md
@@ -1,15 +1,10 @@
---
title: Why Perl 6?
-date: 2018-02-05 18:22:20
-tags: Perl6 Raku
-description: >
- I've grown quite fond of Perl 6 the more I learn about it, yet the general
- developer community still seems to think Perl is a dirty word. In this
- article, I will detail some of the features that make me like Perl 6, and why
- I try to use it wherever possible.
+date: 2018-02-05
+tags:
+- Perl6
+- Raku
---
-= Why Perl 6?
-:toc: preamble
For about a year now, I've been working in Perl 6. Telling this to other people
often brings about some confused faces. I've grown quite fond of Perl 6 the
@@ -21,27 +16,25 @@ make me like Perl 6, and why I try to use it wherever possible.
Whet creating an application, you usually want to be able to specify some
arguments at runtime. Most times this happens using command line arguments or
options. Perl 6 allows you to specify these in the
-https://docs.perl6.org/language/functions#index-entry-MAIN[`MAIN`] subroutine
+[`MAIN`](https://docs.perl6.org/language/functions#index-entry-MAIN) subroutine
signature.
For instance, if I want the application to accept two string arguments, I can
do it as easy as this:
-[source,perl6]
-----
+```raku
sub MAIN (
Str $arg-one,
Str $arg-two,
) {
...
}
-----
+```
Now, if you wanted to add an option like `--output=/path/to/file`, you can do
it just like this:
-[source,perl6]
-----
+```raku
sub MAIN (
Str $arg-one,
Str $arg-two,
@@ -49,28 +42,27 @@ sub MAIN (
) {
...
}
-----
+```
By default, if there's a `MAIN` available in your Perl 6 program, but the
arguments or options supplied by the user are incorrect, it will display the
right way to invoke the command, called the
-https://docs.perl6.org/language/functions#index-entry-USAGE[`USAGE`]. Ofcourse,
-this message can be changed if you wish, but the default is quite good for most
-use-cases.
+[`USAGE`](https://docs.perl6.org/language/functions#index-entry-USAGE).
+Ofcourse, this message can be changed if you wish, but the default is quite good
+for most use-cases.
However, sometimes you want to add a little explanation to what the argument or
option is intended for. Just for a liitle bit of additional user friendliness.
Fear not, for this is also already covered by the defaults. In Perl, there was
POD to document your code. In Perl 6, we have
-https://docs.perl6.org/language/glossary#index-entry-POD[POD] as well. And
+[POD](https://docs.perl6.org/language/glossary#index-entry-POD) as well. And
these comments can be inspected at runtime to provide the user some
information. And that's exactly what the default `USAGE` also does. So if you
want to add some helpful comments to the arguments or the program itself,
simply add the comments where you want them:
-[source,perl6]
-----
+```raku
#| This is a sample program, just to showcase the awesome stuff available in
#| Perl 6.
sub MAIN (
@@ -80,9 +72,10 @@ sub MAIN (
) {
...
}
-----
+```
+
+## Unicode
-== Unicode
What if you could support all languages with a single implementation? That's
where unicode comes in. And Perl 6 currently has the best support for Unicode
out of all programming languages available. Its only real competitor seems to
@@ -98,93 +91,88 @@ For instance, if you're trying to do any kind of math, you can just use the
π character as a regular character. Or use the ² to get the square of a certain
number. This little piece is completely valid in Perl 6:
-[source,perl6]
-----
+```raku
my $a = $r² ÷ π;
-----
+```
Now, if you're thinking "that looks neat, but how am I ever going to write
-these?", do not worry. Most operating systems and many editors have tools to
-let you input these. For instance, using `vim` with
-https://github.com/vim-perl/vim-perl6[`vim-perl6`], you can just write "pi" and
-hit space (or type any non-alphabetical character).
+these?", do not worry. Most operating systems and many editors have tools to let
+you input these. For instance, using `vim` with
+[`vim-perl6`](https://github.com/vim-perl/vim-perl6), you can just write "pi"
+and hit space (or type any non-alphabetical character).
But not everyone is using an OS or an editor that makes it easy. And for those
-people, Perl 6 simply supports using
-https://docs.perl6.org/language/unicode_ascii[ascii based operators]. The
-previous block could also be written as follows:
+people, Perl 6 simply supports using [ASCII based
+operators](https://docs.perl6.org/language/unicode_ascii). The previous block
+could also be written as follows:
-[source,perl6]
-----
+```raku
my $a = $r ^ 2 / pi;
-----
+```
As unicode becomes more accepted, input methods will hopefully improve to make
input easier for everyone in the long run. Those who can already input it
easily don't have to wait for this future, Perl 6 already supports it.
-== Multithreading
+## Multithreading
+
Multi-core processors are virtually everywhere these days. Yet many programming
languages still don't support multithreaded application development natively,
if at all. In Perl 6, running something in a different thread is as easy as
-wrapping it in a https://docs.perl6.org/routine/start[`start`] block:
+wrapping it in a [`start`](https://docs.perl6.org/routine/start) block:
-[source,perl6]
-----
+```raku
start {
do-something();
}
-----
+```
-`start` returns a https://docs.perl6.org/type/Promise[`Promise`], which you can
+`start` returns a [`Promise`](https://docs.perl6.org/type/Promise), which you can
store in a scalar variable just like any other object. You can check on whether
the `Promise` has completed already and check whether it died, for instance.
Other aspects which can often be spread over multiple threads are loops or
maps. For instance, consider the following
-https://docs.perl6.org/routine/map[map] function:
+[`map`](https://docs.perl6.org/routine/map) function:
-[source,perl6]
-----
+```raku
@cats.map: {
$^cat.pat;
}
-----
+```
This will pat each cat in turn, in the order they appear in the list. But you
can speed up the patting process by patting multiple cats at the same time. And
to get there, all you need to do is add a
-https://docs.perl6.org/routine/race[`race`]:
+[`race`](https://docs.perl6.org/routine/race):
-[source,perl6]
-----
+```raku
@cats.race.map: {
$^cat.pat;
}
-----
+```
This will attempt to pat the cats over multiple threads, speeding up the
process to pat all the cats. If the result of the pattings needs to be in the
same order as the patting order, you use
-https://docs.perl6.org/routine/hyper[`hyper`] instead of `race`:
+[`hyper`](https://docs.perl6.org/routine/hyper) instead of `race`:
-[source,perl6]
-----
+```raku
@cats.hyper.map: {
$^cat.pat;
}
-----
+```
+
+## Object orientation
-== Object orientation
Object oriented programming seems to be getting out of fashion with the new
generation of developers. But it's still in wide use, being taught at most
universities, and is often easy to explain to new developers as well.
-And Perl 6 has https://docs.perl6.org/language/classtut#index-entry-OOP[OO]
+And Perl 6 has [OO](https://docs.perl6.org/language/classtut#index-entry-OOP)
support built into its core:
-[source,perl6]
-----
+```raku
class Foo
{
has Str $some-field;
@@ -195,15 +183,14 @@ class Foo
...
}
}
-----
+```
You can also have
-https://docs.perl6.org/language/glossary#index-entry-Multi-Dispatch[multi-dispatch]
+[multi-dispatch](https://docs.perl6.org/language/glossary#index-entry-Multi-Dispatch)
methods on your classes, which are methods with the same names, but accepting
different arguments or argument types. For instance:
-[source,perl6]
-----
+```raku
class Foo
{
multi method bar (
@@ -218,41 +205,42 @@ class Foo
...
}
}
-----
+```
Which method is being used will be decided by the type of argument is being
-passed in, in this case either a https://docs.perl6.org/type/Str[`Str`] or an
-https://docs.perl6.org/type/Int[`Int`].
+passed in, in this case either a [`Str`](https://docs.perl6.org/type/Str) or an
+[`Int`](https://docs.perl6.org/type/Int).
+
+## Functional programming
-== Functional programming
Whilst OO is considered being old more and more, functional programming is
gaining ground. And this paradigm is fully supported in the core of Perl 6 as
well. You've seen the `map` example already while patting cats earlier, for
instance.
But there's much more on the functional playing field, such as the
-https://docs.perl6.org/routine/==%3E[`=\=>`] operator, known as the
-https://docs.perl6.org/language/operators#infix_==%3E[feed operator]. It simply
+[`==>`](https://docs.perl6.org/routine/==%3E) operator, known as the [`feed
+operator`](https://docs.perl6.org/language/operators#infix_==%3E). It simply
passed the output of a statement as the last argument to the next statement:
-[source,perl6]
-----
+```raku
@grumpy-cats
==> feed()
==> pat()
==> snuggle()
==> my @happy-cats;
-----
+```
This will take the `@grumpy-cats`, feed them, pat them, snuggle them and put
the result into `@happy-cats`. You could've chained the calls using a `.`
-instead, and Perl 6 allows you to do this too. But the `=\=>` looks much more
+instead, and Perl 6 allows you to do this too. But the `==>` looks much more
readable to me, which is why I prefer using this instead.
I'm still exploring the functional programming field myself, but these few
things have made me happy exploring it.
-== Community
+## Community
+
(Almost) last, but certainly not least, the Perl 6 community is amazing. It's
been the friendliest bunch I've been with, both on IRC, their mailing lists and
in real life. Everyone is welcoming, and they try to help you whenever they
@@ -262,17 +250,20 @@ Community is important to help you out whenever you get stuck for whatever
reason. A friendly community is the best you can get here to keep you a happy
developer yourself as well.
-== Other little aspects
+## Other little aspects
+
There's a few neat things I can do in Perl 6 that I can't do in (most) other
languages, but aren't important enough to warrant a large section to show them
off.
-=== Dashes in names
+### Dashes in names
+
You can use dashes in names: Things like `my $foo-bar` is valid, just like
`method foo-bar`. It's nothing big on itself, but I've found it makes reading
code much more enjoyable than pascalCase, CamelCase or snake_case.
-=== Gradual typing
+### Gradual typing
+
You don't *need* to use types in Perl 6. But when you want to use them (for
making use of multi-dispatch, for example), you can just start using them. If
types are added, the compiler will make sure the types are correct. If not, you
diff --git a/src/_posts/2018-03-20-perl6-introduction-to-application-programming.adoc b/content/posts/2018/2018-03-20-perl6-introduction-to-application-programming.md
index fc00bd3..2b8ea48 100644
--- a/src/_posts/2018-03-20-perl6-introduction-to-application-programming.adoc
+++ b/content/posts/2018/2018-03-20-perl6-introduction-to-application-programming.md
@@ -1,34 +1,35 @@
---
title: "Perl 6 - Introduction to application programming"
-date: 2018-03-20 11:08:00
-tags: Tutorial Perl6 Assixt GTK Programming Raku
-layout: post
-authors:
- - ["Patrick Spek", "https://tyil.nl"]
+date: 2018-03-20
+tags:
+- Tutorial
+- Perl6
+- Assixt
+- GTK
+- Programming
+- Raku
---
-= Perl 6 - Introduction to application programming
-:toc: preamble
In this tutorial, I'll be guiding you through creating a simple application in
-Perl 6. If you don't have Perl 6 installed yet, get the
-http://rakudo.org/how-to-get-rakudo/[Rakudo Star] distribution for your OS.
-Alternatively, you can use the https://hub.docker.com/_/rakudo-star/[Docker
-image].
+Perl 6. If you don't have Perl 6 installed yet, get the [Rakudo
+Star](http://rakudo.org/how-to-get-rakudo/) distribution for your OS.
+Alternatively, you can use the [Docker
+image](https://hub.docker.com/_/rakudo-star/).
The application itself will be a simple dice-roller. You give it a number of
dice to roll, and the number of sides the die has. We'll start off by creating
it as a console application, then work to make it a GUI as well with the
`GTK::Simple` module.
-== Preparation
+## Preparation
+
First, you'll want to install the libgtk headers. How to get these depends on
your distro of choice. For Debian-based systems, which includes Ubuntu and
derivatives, this command would be the following `apt` invocation:
-[source]
-----
+```txt
$ apt install libgtk-3-dev
-----
+```
For other distros, please consult your documentation.
@@ -36,16 +37,14 @@ To ease up module/application building, I'll use `App::Assixt`. This module
eases up on common tasks required for building other modules or applications.
So we'll start by installing this module through `zef`.
-[source]
-----
+```txt
$ zef install App::Assixt
-----
+```
-[NOTE]
-====
+{{< admonition title="note" >}}
You may need to rehash your `$PATH` as well, which can be done using `hash -r`
on `bash`, or `rehash` for `zsh`. For other shells, consult your manual.
-====
+{{< / admonition >}}
Next up, we can use `assixt` to create the new skeleton of our application,
with the `new` subcommand. This will ask for some user input, which will be
@@ -53,56 +52,63 @@ recorded in the `META6.json`, a json-formatted file to keep track of meta
information about the module. `assixt` should take care of this file for you,
so you never need to actually deal with it.
-[source]
-----
+```txt
$ assixt new
-----
+```
+
+### assixt input
-=== assixt input
Since the `assixt new` command requires some input, I'll walk through these
options and explain how these would affect your eventual application.
-==== Name of the module
+#### Name of the module
+
This is the name given to the module. This will be used for the directory name,
which by default in `assixt` will be `perl6-` prepended to a lower-case version
of the module name. If you ever wish to make a module that is to be shared in
the Perl 6 ecosystem, this should be unique across the entire ecosystem. If
-you're interested in some guidelines, the
-https://pause.perl.org/pause/query?ACTION=pause_namingmodules[PAUSE guidelines]
-seem to apply pretty well to Perl 6 as well.
+you're interested in some guidelines, the [PAUSE
+guidelines](https://pause.perl.org/pause/query?ACTION=pause_namingmodules) seem
+to apply pretty well to Perl 6 as well.
For this application, we'll use `Local::App::Dicer`, but you can use whatever
name you'd prefer here.
-==== Your name
+#### Your name
+
Your name. This will be used as the author's name in the `META6.json`. It is
used to find out who made it, in order to report issues (or words of praise,
of course).
-==== Your email address
+#### Your email address
+
Your email address. Like your name, it will be used in case someone has to
contact you in regards off the module.
-==== Perl 6 version
+#### Perl 6 version
+
This defaults to `c` right now, and you can just hit enter to accept it. In the
future, there will be a Perl 6.d available as well, in which case you can use
this to indicate you want to use the newer features introduced in 6.d. This is
not the case yet, so you just want to go with the default `c` value here.
-==== Module description
+#### Module description
+
A short description of your module, preferably a single sentence. This is
useful to people wondering what the module is for, and module managers can show
to the user.
-==== License key
+#### License key
+
This indicates the license under which your module is distributed. This
defaults to `GPL-3.0`, which I strongly recommend to use. The de-facto
default seems to be `Artistic-2.0`, which is also used for Perl 6 itself.
-This identifier is based on the https://spdx.org/licenses/[SPDX license list].
+This identifier is based on the [SPDZ license list](https://spdx.org/licenses/).
Anything not mentioned in this list is not acceptable. #TODO Clarify why
-== Writing your first test
+## Writing your first test
+
With the creation of the directory structure and metadata being taken care of
by `assixt`, we can now start on writing things. Tests are not mandatory, but
are a great tool for quickly checking if everything works. If you make larger
@@ -114,16 +120,14 @@ Creating the base template for tests, `assixt` can help you out again: `assixt
touch` can create templates in the right location, so you don't have to deal
with it. In this case we want to create a test, which we'll call "basic".
-[source]
-----
+```txt
$ assixt touch test basic
-----
+```
This will create the file `t/basic.t` in your module directory. Its contents
will look as follows:
-[source,perl6]
-----
+```raku
#! /usr/bin/env perl6
use v6.c;
@@ -135,13 +139,12 @@ ok True;
done-testing;
# vim: ft=perl6
-----
+```
The only test it has right now is `ok True`, which will always pass testing. We
will change that line into something more usable for this application:
-[source,perl6]
-----
+```raku
use Local::App::Dicer;
plan 2;
@@ -161,33 +164,32 @@ subtest "Illegal rolls", {
throws-like { roll(-1) }, X::TypeCheck::Binding::Parameter, "Negative rolls are not accepted";
throws-like { roll(1.5) }, X::TypeCheck::Binding::Parameter, "Can't roll half sides";
}
-----
+```
-[NOTE]
-====
+{{< admonition title="note" >}}
Perl 6 allows mathematical characters to make your code more concise, as with
-the ≤ in the above block. If you use http://www.vim.org/[vim], you can make use
-of the https://github.com/vim-perl/vim-perl6[vim-perl6] plugin, which has an
+the ≤ in the above block. If you use [vim](http://www.vim.org/), you can make use
+of the [vim-perl6](https://github.com/vim-perl/vim-perl6) plugin, which has an
option to change the longer, ascii-based ops (in this case `\<=`) into the
shorter unicode based ops (in this case `≤`). This specific feature requires
`let g:perl6_unicode_abbrevs = 1` in your `vimrc` to be enabled with
`vim-perl6`.
If that's not an option, you can use a
-https://en.wikipedia.org/wiki/Compose_key[compose key]. If that is not viable
+[compose key](https://en.wikipedia.org/wiki/Compose_key). If that is not viable
either, you can also stick to using the ascii-based ops. Perl 6 supports both
of them.
-====
+{{< / admonition >}}
This will run 53 tests, split up in two
-https://docs.perl6.org/language/testing#Grouping_tests[subtests]. Subtests are
-used to logically group your tests. In this case, the calls that are correct
-are in one subtest, the calls that should be rejected are in another.
+[subtests](https://docs.perl6.org/language/testing#Grouping_tests). Subtests are
+used to logically group your tests. In this case, the calls that are correct are
+in one subtest, the calls that should be rejected are in another.
The `plan` keywords indicate how many tests should be run. This will help spot
errors in case your expectations were not matched. For more information on
-testing, check out https://docs.perl6.org/language/testing[the Perl 6 docs on
-testing].
+testing, check out [the Perl 6 docs on
+testing](https://docs.perl6.org/language/testing).
We're making use of two test routines, `ok` and `throws-like`. `ok` is a
simple test: if the given statement is truthy, the test succeeds. The other
@@ -198,50 +200,48 @@ second argument is the exception it should throw. The test succeeds if the
right exception is thrown. Both `ok` and `throws-like` accept a descriptive
string as optional last argument.
-=== Running the tests
+### Running the tests
+
A test is useless if you can't easily run it. For this, the `prove` utility
exists. You can use `assixt test` to run these tests properly as well, saving
you from having to manually type out the full `prove` command with options.
-[source]
-----
+```txt
$ assixt test
-----
+```
You might notice the tests are currently failing, which is correct. The
`Local::App::Dicer` module doesn't exist yet to test against. We'll be working
on that next.
-[NOTE]
-====
+{{< admonition title="note" >}}
For those interested, the command run by `assixt test` is `prove -e "perl6
-Ilib" t`. This will include the `lib` directory into the `PERL6PATH` to be
able to access the libraries we'll be making. The `t` argument specifies the
directory containing the tests.
-====
+{{< / admonition >}}
+
+## Creating the library
-== Creating the library
Again, let's start with a `assixt` command to create the base template. This
time, instead of `touch test`, we'll use `touch lib`.
-[source]
-----
+```txt
$ assixt touch unit Local::App::Dicer
-----
+```
This will generate a template file at `lib/Local/App/Dicer.pm6` which some
defaults set. The file will look like this.
-[source,perl6]
-----
+```raku
#! /usr/bin/env false
use v6.c;
unit module Local::App::Dicer;
-----
+```
-The first line is a https://en.wikipedia.org/wiki/Shebang_(Unix)[shebang]. It
+The first line is a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)). It
informs the shell what to do when you try to run the file as an executable
program. In this case, it will run `false`, which immediately exits with a
non-success code. This file needs to be run as a Perl 6 module file, and
@@ -253,26 +253,25 @@ line informs the name of this module, which is `Local::App::Dicer`. Beneath
this, we can add subroutines, which can be exported. These can then be accessed
from other Perl 6 files that `use` this module.
-=== Creating the `roll` subroutine
+### Creating the `roll` subroutine
+
Since we want to be able to `roll` a die, we'll create a subroutine to do
exactly that. Let's start with the signature, which tells the compiler the name
of the subroutine, which arguments it accepts, their types and what type the
subroutine will return.
-[TIP]
-====
+{{< admonition title="tip" >}}
Perl 6 is gradually typed, so all type information is optional. The subroutine
arguments are optional too, but you will rarely want a subroutine that doesn't
have an argument list.
-====
+{{< / admonition >}}
-[source,perl6]
-----
+```raku
sub roll($sides) is export
{
$sides
}
-----
+```
Let's break this down.
@@ -288,25 +287,24 @@ Let's break this down.
If you run `assixt test` now, you can see it only fails 1/2 subtests:
-[source]
-----
+```raku
# TODO: Add output of failing tests
-----
+```
Something is going right, but not all of it yet. The 3 tests to check for
illegal rolls are still failing, because there's no constraints on the input of
the subroutine.
-=== Adding constraints
+### Adding constraints
+
The first constraint we'll add is to limit the value of `$sides` to an `Int:D`.
The first part of this constraint is common in many languages, the `Int` part.
The `:D` requires the argument to be **defined**. This forces an actual
existing instance of `Int`, not a `Nil` or undefined value.
-[source,perl6]
-----
+```raku
sub roll(Int:D $sides) is export
-----
+```
Fractional input is no longer allowed, since an `Int` is always a round number.
But an `Int` is still allowed to be 0 or negative, which isn't possible in a
@@ -314,17 +312,17 @@ dice roll. Nearly every language will make you solve these two cases in the
subroutine body. But in Perl 6, you can add another constraint in the signature
that checks for exactly that:
-[source,perl6]
-----
+```raku
sub roll(Int:D $sides where $sides > 0) is export
-----
+```
The `where` part specifies additional constraints, in this case `$sides > 0`.
So now, only round numbers larger than 0 are allowed. If you run `assixt test`
again, you should see all tests passing, indicating that all illegal rolls are
now correctly disallowed.
-=== Returning a random number
+### Returning a random number
+
So now that we can be sure that the input is always correct, we can start on
making the output more random. In Perl 6, you can take a number and call
`.rand` on it, to get a random number between 0 and the value of the number you
@@ -332,31 +330,29 @@ called it on. This in turn can be rounded up to get a number ranging from 1 to
the value of the number you called `.rand` on. These two method calls can also
be changed to yield concise code:
-[source,perl6]
-----
+```raku
sub roll(Int:D $sides where $sides > 0) is export
{
$sides.rand.ceiling
}
-----
+```
That's all we need from the library itself. Now we can start on making a usable
program out of it.
-== Adding a console interface
+## Adding a console interface
+
First off, a console interface. `assixt` can `touch` a starting point for an
executable script as well, using `assixt touch bin`:
-[source]
-----
+```txt
$ assixt touch bin dicer
-----
+```
This will create the file `bin/dicer` in your repository, with the following
template:
-[source,perl6]
-----
+```raku
#! /usr/bin/env perl6
use v6.c;
@@ -365,7 +361,7 @@ sub MAIN
{
}
-----
+```
The program will run the `MAIN` sub by default. We want to slightly change this
`MAIN` signature though, since we want to accept user input. And it just so
@@ -374,20 +370,18 @@ signature in Perl 6. This lets us add constraints to the parameters and give
them better names with next to no effort. We want to accept two numbers, one
for the number of dice, and one for the number of sides per die:
-[source,perl6]
-----
+```raku
sub MAIN(Int:D $dice, Int:D $sides where { $dice > 0 && $sides > 0 })
-----
+```
Here we see the `where` applying constraints again. If you try running this
program in its current state, you'll have to run the following:
-[source]
-----
+```txt
$ perl6 -Ilib bin/dicer
Usage:
bin/dicer <dice> <sides>
-----
+```
This will return a list of all possible ways to invoke the program. There's one
slight problem right now. The usage description does not inform the user that
@@ -398,8 +392,7 @@ To do that, let's add a `use` statement to our `lib` directory, and call the
`roll` function we created earlier. The `bin/dicer` file will come to look as
follows:
-[source,perl6]
-----
+```raku
#! /usr/bin/env perl6
use v6.c;
@@ -410,41 +403,39 @@ sub MAIN(Int:D $dice, Int:D $sides where { $dice > 0 && $sides > 0 })
{
say $dice × roll($sides)
}
-----
+```
-[NOTE]
-====
+{{< admonition title="note" >}}
Just like the `≤` character, Perl 6 allows to use the proper multiplication
character `×` (this is not the letter `x`!). You can use the more widely known
`*` for multiplication as well.
-====
+{{< / admonition >}}
If you run the program with the arguments `2` and `20` now, you'll get a random
number between 2 and 40, just like we expect:
-[source]
-----
+```txt
$ perl6 -Ilib bin/dicer 2 20
18
-----
+```
+
+### The usage output
-=== The usage output
Now, we still have the trouble of illegal number input not clearly telling
-what's wrong. We can do a neat trick with
-https://docs.perl6.org/language/functions#index-entry-USAGE[the USAGE sub] to
-achieve this. Perl 6 allows a subroutine with the name `USAGE` to be defined,
-overriding the default behaviour.
+what's wrong. We can do a neat trick with [the `USAGE`
+sub](https://docs.perl6.org/language/functions#index-entry-USAGE) to achieve
+this. Perl 6 allows a subroutine with the name `USAGE` to be defined, overriding
+the default behaviour.
Using this, we can generate a friendlier message informing the user what they
need to supply more clearly. The `USAGE` sub would look like this:
-[source,perl6]
-----
+```raku
sub USAGE
{
say "Dicer requires two positive, round numbers as arguments."
}
-----
+```
If you run the program with incorrect parameters now, it will show the text
from the `USAGE` subroutine. If the parameters are correct, it will run the
@@ -452,28 +443,29 @@ from the `USAGE` subroutine. If the parameters are correct, it will run the
You now have a working console application in Perl 6!
-== Making a simple GUI
+## a simple GUI
+
But that's not all. Perl 6 has a module to create GUIs with the
-https://www.gtk.org/[GTK library] as well. For this, we'll use the
-https://github.com/perl6/gtk-simple[`GTK::Simple`] module.
+[GTK library](https://www.gtk.org/) as well. For this, we'll use the
+[`GTK::Simple`](https://github.com/perl6/gtk-simple) module.
You can add this module as a dependency to the `Local::App::Dicer` repository
with `assixt` as well, using the `depend` command. By default, this will also
install the dependency locally so you can use it immediately.
-[source]
-----
+```txt
$ assixt depend GTK::Simple
-----
+```
+
+### Multi subs
-=== Multi subs
Next, we could create another executable file and call it `dicer-gtk`. However,
I can also use this moment to introduce
-https://docs.perl6.org/language/glossary#index-entry-multi-method[multi
-methods]. These are subs with the same name, but differing signatures. If a
-call to such a sub could potentially match multiple signatures, the most
-specific one will be used. We will add another `MAIN` sub, which will be called
-when `bin/dicer` is called with the `--gtk` parameter.
+[multi-methods](https://docs.perl6.org/language/glossary#index-entry-multi-method).
+These are subs with the same name, but differing signatures. If a call to such a
+sub could potentially match multiple signatures, the most specific one will be
+used. We will add another `MAIN` sub, which will be called when `bin/dicer` is
+called with the `--gtk` parameter.
We should also update the `USAGE` sub accordingly, of course. And while we're
at it, let's also include the `GTK::Simple` and `GTK::Simple::App` modules. The
@@ -481,8 +473,7 @@ first pulls in all the different GTK elements we will use later on, while the
latter pulls in the class for the base GTK application window. The updated
`MAIN`, `USAGE` and `use` parts will now look like this:
-[source,perl6]
-----
+```raku
use Local::App::Dicer;
use GTK::Simple;
use GTK::Simple::App;
@@ -501,7 +492,7 @@ sub USAGE
{
say "Launch Dicer as a GUI with --gtk, or supply two positive, round numbers as arguments.";
}
-----
+```
There's a new thing in a signature header here as well, `:$gtk`. The `:` in
front of it makes it a named argument, instead of a positional one. When used
@@ -511,15 +502,15 @@ Its use in general subroutine signatures is explained in the next chapter.
Running the application with `--gtk` gives no output now, because the body only
contains a comment. Let's fix that.
-=== Creating the window
+### Creating the window
+
First off, we require a `GTK::Simple::App` instance. This is the main window,
in which we'll be able to put elements such as buttons, labels, and input
fields. We can create the `GTK::Simple::App` as follows:
-[source,perl6]
-----
+```raku
my GTK::Simple::App $app .= new(title => "Dicer");
-----
+```
This one line brings in some new Perl 6 syntax, namely the `.=` operator.
There's also the use of a named argument in a regular subroutine.
@@ -528,15 +519,15 @@ The `.=` operator performs a method on the variable on the left. In our case,
it will call the `new` subroutine, which creates a new instance of the
`GTK::Simple::App` class. This is commonly referred to as the **constructor**.
-The named argument list (`title \=> "Dicer"`) is another commonly used feature
+The named argument list (`title => "Dicer"`) is another commonly used feature
in Perl 6. Any method can be given a non-positional, named parameter. This is
done by appending a `:` in front of the variable name in the sub signature.
This has already been used in our code, in `multi sub MAIN(Bool :$gtk where
$gtk == True)`. This has a couple of benefits, which are explained in the
-https://docs.perl6.org/type/Signature#index-entry-positional_argument_%28Signature%29_named_argument_%28Signature%29[Perl
-6 docs on signatures].
+[Perl 6 docs on signatures](https://docs.perl6.org/type/Signature#index-entry-positional_argument_%28Signature%29_named_argument_%28Signature%29).
+
+### Creating the elements
-=== Creating the elements
Next up, we can create the elements we'd like to have visible in our
application window. We needed two inputs for the console version, so we'll
probably need two for the GUI version as well. Since we have two inputs, we
@@ -548,19 +539,19 @@ elements in total:
- 2 entries
- 1 button
-[source,perl6]
-----
+```raku
my GTK::Simple::Label $label-dice .= new(text => "Amount of dice");
my GTK::Simple::Label $label-sides .= new(text => "Dice value");
my GTK::Simple::Label $label-result .= new(text => "");
my GTK::Simple::Entry $entry-dice .= new(text => 0);
my GTK::Simple::Entry $entry-sides .= new(text => 0);
my GTK::Simple::Button $button-roll .= new(label => "Roll!");
-----
+```
This creates all elements we want to show to the user.
-=== Show the elements in the application window
+### Show the elements in the application window
+
Now that we have our elements, let's put them into the application window.
We'll need to put them into a layout as well. For this, we'll use a grid. The
`GTK::Simple::Grid` constructor takes pairs, with the key being a tuple
@@ -570,8 +561,7 @@ coordinates, y coordinates, width and height respectively.
This in turn takes us to the following statement:
-[source,perl6]
-----
+```raku
$app.set-content(
GTK::Simple::Grid.new(
[0, 0, 1, 1] => $label-dice,
@@ -582,7 +572,7 @@ $app.set-content(
[0, 3, 2, 1] => $label-result,
)
);
-----
+```
Put a `$app.run` beneath that, and try running `perl6 -Ilib bin/dicer --gtk`.
That should provide you with a GTK window with all the elements visible in the
@@ -590,16 +580,16 @@ position we want. To make it a little more appealing, we can add a
`border-width` to the `$app`, which adds a margin between the border of the
application window, and the grid inside the window.
-[source,perl6]
-----
+```raku
$app.border-width = 20;
$app.run;
-----
+```
You may notice that there's no `()` after the `run` method call. In Perl 6,
these are optional if you're not supplying any arguments any way.
-=== Binding an action to the button
+### Binding an action to the button
+
Now that we have a visible window, it's time to make the button perform an
action. The action we want to execute is to take the values from the two
inputs, roll the correct number of dice with the correct number of sides, and
@@ -609,11 +599,10 @@ The base code for binding an action to a button is to call `.clicked.tap` on it,
and provide it with a code block. This code will be executed whenever the
button is clicked.
-[source,perl6]
-----
+```raku
$button-roll.clicked.tap: {
};
-----
+```
You see we can also invoke a method using `:`, and then supplying its
arguments. This saves you the trouble of having to add additional `( )` around
@@ -622,8 +611,7 @@ another set of parens.
Next, we give the code block something to actually perform:
-[source,perl6]
-----
+```raku
$button-roll.clicked.tap: {
CATCH {
$label-result.text = "Can't roll with those numbers";
@@ -633,7 +621,7 @@ $button-roll.clicked.tap: {
$label-result.text = ($entry-dice.text.Int × roll($entry-sides.text.Int)).Str;
};
-----
+```
There's some new things in this block of code, so let's go over these.
@@ -649,14 +637,15 @@ There's some new things in this block of code, so let's go over these.
circumstances can result in cleaner code. It's used here because it improves
the readability of the code, and to show that it's possible.
-== The completed product
+## The completed product
+
And with that, you should have a dice roller in Perl 6, with both a console and
GTK interface. Below you can find the complete, finished sourcefiles which you
should have by now.
-=== t/basic.t
-[source,perl6]
-----
+### t/basic.t
+
+```raku
#! /usr/bin/env perl6
use v6.c;
@@ -685,11 +674,11 @@ subtest "Illegal rolls", {
done-testing;
# vim: ft=perl6
-----
+```
-=== lib/Local/App/Dicer.pm6
-[source,perl6]
-----
+### lib/Local/App/Dicer.pm6
+
+```raku
#! /usr/bin/env false
use v6.c;
@@ -700,11 +689,11 @@ sub roll(Int:D $sides where $sides > 0) is export
{
$sides.rand.ceiling;
}
-----
+```
+
+### bin/dicer
-=== bin/dicer
-[source,perl6]
-----
+```raku
#! /usr/bin/env perl6
use v6.c;
@@ -758,9 +747,10 @@ sub USAGE
{
say "Launch Dicer as a GUI with --gtk, or supply two positive, round numbers as arguments.";
}
-----
+```
+
+## Installing your module
-== Installing your module
Now that you have a finished application, you probably want to install it as
well, so you can run it by calling `dicer` in your shell. For this, we'll be
using `zef`.
@@ -768,17 +758,15 @@ using `zef`.
To install a local module, tell `zef` to try and install the local directory
you're in:
-[source]
-----
+```txt
$ zef install .
-----
+```
This will resolve the dependencies of the local module, and then install it.
You should now be able to run `dicer` from anywhere.
-[WARNING]
-====
+{{< admonition title="warning" >}}
With most shells, you have to "rehash" your `$PATH` as well. On `bash`, this is
done with `hash -r`, on `zsh` it's `rehash`. If you're using any other shell,
please consult the manual.
-====
+{{< / admonition >}}
diff --git a/src/_posts/2018-05-07-sparrowdo-getting-started.adoc b/content/posts/2018/2018-05-07-sparrowdo-getting-started.md
index cbe2201..419e98d 100644
--- a/src/_posts/2018-05-07-sparrowdo-getting-started.adoc
+++ b/content/posts/2018/2018-05-07-sparrowdo-getting-started.md
@@ -1,50 +1,52 @@
---
-date: 2018-05-07 14:04:43
-tags: Tutorial Perl6 Sparrowdo Raku LoneStar
-description: >
- Nondescript
+title: Sparrowdo - Getting Started
+date: 2018-05-07
+tags:
+- LoneStar
+- Perl6
+- Raku
+- Sparrowdo
+- Tutorial
---
-= Sparrowdo - Getting started
-:toc: preamble
-https://github.com/melezhik/sparrowdo[Sparrowdo] is a Perl 6 project to
+[Sparrowdo](https://github.com/melezhik/sparrowdo) is a Perl 6 project to
facilitate automatic configuration of systems. There's a
-https://sparrowhub.org/[repository of useful modules] to make specific cases
+[repository of useful modules](https://sparrowhub.org/) to make specific cases
easier to work with, but the
-https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md[Core DSL] can
+[Core DLS](https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md) can
already take care of many tasks. In this tutorial, I'll guide you through
setting up Sparrowdo, bootstrapping it onto your local system, writing a task
and running it.
-== Install Sparrowdo
-Sparrowdo is a http://perl6.org/[Perl 6] project, so you'll need to have Perl 6
-installed. We'll also use the Perl 6 package manager
-https://github.com/ugexe/zef/[zef] to install Sparrowdo itself. Luckily for us,
-there's a stable distribution of Perl 6 with everything we need added to it,
-called https://rakudo.org/files[Rakudo Star]. And to make it easier for
+## Install Sparrowdo
+
+Sparrowdo is a [Perl 6]http://perl6.org/) project, so you'll need to have Perl
+6 installed. We'll also use the Perl 6 package manager
+[zef](https://github.com/ugexe/zef/) to install Sparrowdo itself. Luckily for
+us, there's a stable distribution of Perl 6 with everything we need added to it,
+called [Rakudo Star](https://rakudo.org/files). And to make it easier for
GNU+Linux users, I wrote a tool to fetch the latest Rakudo Star release, compile
-it and install it, called https://github.com/Tyil/lonestar[LoneStar]. Since this
-tutorial will aim at GNU+Linux users, I'll use that to install Perl 6.
+it and install it, called [LoneStar](https://github.com/Tyil/lonestar). Since
+this tutorial will aim at GNU+Linux users, I'll use that to install Perl 6.
+
+### Installing Perl 6 with LoneStar
-=== Installing Perl 6 with LoneStar
LoneStar is a Bash application to download, compile and set up Perl 6. It's a
standalone application, meaning you don't have to install it to your system. You
can just run it from the source directory. First, we'll have to get the source
directory, which we'll do using `git`.
-[source,sh]
-----
+```txt
mkdir -p ~/.local/src
git clone https://github.com/tyil/lonestar.git ~/.local/src/lonestar
cd !$
-----
+```
Now you have the LoneStar sources available in `~/.local/src/lonestar`. You can
run the application using `./bin/lonestar`. Running it, you'll get some help
output:
-[source]
-----
+```txt
$ ./bin/lonestar
lonestar - Installation manager for Rakudo Star
@@ -57,7 +59,7 @@ Actions:
path [version=latest]
reinstall [version=latest]
upgrade
-----
+```
We'll be needing the `install` action to get Perl 6 installed, and the `init`
action to configure the `$PATH` environment variable. Depending on your
@@ -65,53 +67,51 @@ hardware, `install` may take a couple minutes as it will compile Rakudo Perl 6
and install some base modules. You might want to grab a drink during this
period.
-[source]
-----
+```txt
$ ./bin/lonestar install
$ eval $(./bin/lonestar init)
$ perl6 -v
This is Rakudo Star version 2018.04.1 built on MoarVM version 2018.04.1
implementing Perl 6.c.
-----
+```
-[NOTE]
-====
+{{< admonition title="note" >}}
If there's a newer version available of Rakudo Star, the version numbers given
by `perl6 -v` will differ for you.
-====
+{{< / admonition >}}
+
+### Installing Sparrowdo with zef
-=== Installing Sparrowdo with zef
Now that you have Perl 6 available and installed, you can continue on using
`zef` to install Sparrowdo. `zef` is bundled with Rakudo Star, so you don't have
to do anything to get it working.
-[source,sh]
-----
+```txt
zef install Sparrowdo
-----
+```
This will instruct `zef` to install Sparrowdo and all its dependencies. This can
take a couple minutes, again depending on the hardware of your machine.
-== Bootstrapping your system
+## Bootstrapping your system
+
The first step to working with Sparrowdo is bootstrapping the system you wish to
use it with. In this case, that'll be the local system. There's a `--bootstrap`
option to do this automatically.
-[source,sh]
-----
+```txt
sparrowdo --bootstrap
-----
+```
-[TIP]
-====
+{{< admonition title="tip" >}}
If you wish to bootstrap a remote system, you can use the `--host` option to
specify the system. For example: `sparrowdo --host=192.168.1.2 --bootstrap`.
-====
+{{< / admonition >}}
Now your system is ready to be configured automatically using Sparrowdo!
-== Sparrowfiles
+## Sparrowfiles
+
Sparrowfiles are the files that describe the tasks Sparrow should execute to
get you the configuration you want. They are valid Perl 6 code, and call the
subroutines (or _sparrowtasks_) that will handle the actual actions. By default,
@@ -122,30 +122,29 @@ To make our sample, we'll create a new directory to work in, so we have clean
directory that can be shared easily. You can also keep this directory under
version control, so you can distribute the `sparrowfile` with all its templates.
-[TIP]
-====
+{{< admonition title="tip" >}}
If you just want to create an empty directory to test things in, without
"polluting" the rest of your system, just call `cd -- "$(mktemp -d)"`. This will
create a temporary directory and change the working directory to there.
-====
+{{< / admonition >}}
I'll be using `~/.local/sparrowdo/local-dns` to work in, as I'll be setting up a
-local dns cache with http://www.thekelleys.org.uk/dnsmasq/doc.html[dnsmasq] for
-the sample code.
+local dns cache with [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html)
+for the sample code.
+
+### Writing a `sparrowfile`
-=== Writing a `sparrowfile`
As noted in the previous paragraph, for the sake of a demo I'll guide you
through creating a `sparrowfile` to install and configure `dnsmasq` as a local
DNS cache. Using your favourite `$EDITOR`, write the following to `sparrowfile`:
-[source,perl6]
-----
+```raku
package-install "dnsmasq";
directory "/etc/dnsmasq.d";
file-create "/etc/dnsmasq.conf", %(content => slurp "dnsmasq.conf");
file-create "/etc/dnsmasq.d/resolv.conf", %(content => slurp "resolv.conf");
service-start "dnsmasq";
-----
+```
This `sparrowfile` will set up the following configuration for `dnsmasq`:
@@ -161,39 +160,36 @@ current directory. So for this to work, you'll need to also create the
appropriate configuration files. Let's start off with the main `dnsmasq`
configuration in `dnsmasq.conf`:
-[source,conf]
-----
+```conf
listen-address=127.0.0.1
no-dhcp-interface=
resolv-file=/etc/dnsmasq.d/resolv.conf
-----
+```
This will make `dnsmasq` listen on the loopback interface, so it'll only be able
to be used by the local machine. Furthermore, DHCP functionality will be
disabled, and the upstream resolvers are read from `/etc/dnsmasq.d/resolv.conf`.
The contents of that file are as follows:
-[source,conf]
-----
+```conf
nameserver 37.235.1.174
nameserver 37.235.1.177
-----
+```
-These nameservers are part of the https://freedns.zone/en/[FreeDNS] project. You
-can of course use whatever other DNS provider you want to use as your upstream
-servers. Now, for `dnsmasq` to be used, you will also need to set your machine's
-DNS resolvers to point to the `dnsmasq` service. This is defined in
+These nameservers are part of the [FreeDNS](https://freedns.zone/en/) project.
+You can of course use whatever other DNS provider you want to use as your
+upstream servers. Now, for `dnsmasq` to be used, you will also need to set your
+machine's DNS resolvers to point to the `dnsmasq` service. This is defined in
`/etc/resolv.conf`, so lets append the following to our `sparrowfile` to set
that up.
-[source,conf]
-----
+```conf
bash "chattr -i /etc/resolv.conf";
file-delete "/etc/resolv.conf";
file-create "/etc/resolv.conf", %(content => "nameserver 127.0.0.1");
bash "chattr +i /etc/resolv.conf";
-----
+```
This will remove the "immutable" attribute from `/etc/resolv.conf` if it's set.
Next it will remove the current `/etc/resolv.conf` and write out a new one which
@@ -202,33 +198,31 @@ only refers to the local machine as DNS resolver. This is to ensure an existing
adds back the immutable attribute to the file, so other processes won't
overwrite it.
-=== Running the `sparrowfile`
+### Running the `sparrowfile`
+
To run the `sparrowfile` and get the setup you desire, run the `sparrowdo`
command with `--local_mode` and wait.
-[source]
-----
+```txt
sparrowdo --local_mode
-----
+```
-[NOTE]
-====
+{{< admonition title="note" >}}
If you want to run this on a remote machine to configure that one instead, you
can use `--host=<ip>` instead of `--local_mode`.
-====
+{{< / admonition >}}
You can check whether it actually worked by inspecting the files in
`/etc/dnsmasq.d` and your `/etc/resolv.conf`. The easiest way to check their
contents would be by using `cat`:
-[source]
-----
+```txt
cat /etc/dnsmasq.d/dnsmasq.conf
cat /etc/dnsmasq.d/resolv.conf
cat /etc/resolv.conf
-----
+```
-== Closing words
+## Closing words
You should now have a working local DNS setup, configured programmatically
through Sparrowdo. This allows you easily get it working on other machines as
diff --git a/src/_posts/2018-08-15-the-perl-conference-in-glasgow.adoc b/content/posts/2018/2018-08-15-the-perl-conference-in-glasgow.md
index 6fd8f90..3c01edc 100644
--- a/src/_posts/2018-08-15-the-perl-conference-in-glasgow.adoc
+++ b/content/posts/2018/2018-08-15-the-perl-conference-in-glasgow.md
@@ -1,33 +1,97 @@
---
+title: The Perl Conference in Glasgow
date: 2018-08-23
-tags: Perl Conference
-description: >
- My feedback and comments on some of the talks I attended during The Perl
- Conference in Glasgow, in 2018.
+tags:
+- Conference
+- Perl
---
-= The Perl Conference in Glasgow
-:toc: preamble
This year the European Perl Conference was hosted in Glasgow, and of course
I've attended a number of presentations there. On some of these, I have some
feedback or comments. These talks, and the feedback I have for them, are
detailed in this blog post.
-== Discourse Without Drama
-
-[NOTE]
-====
-There used to be comments here to show a different perspective to the speaker.
-However, someone's lightning talk has been removed because
-https://act.perlconference.org/tpc-2018-glasgow/news/1568[some people played
-the "offended" card], and no specifics are being published about it. Therefore,
-I cannot make any assertions on what is and what is not allowed, and have to
-assume that criticism of harmful beliefs will be shut down. As such, I have
-removed the comments which used to be here, in an attempt to keep it from
-detracting from the rest of my post.
-====
-
-== European Perl Mongers Organiser's Forum 2018
+{{< admonition title="note" >}}
+The first talk I cover is not so much about Perl, but more about politics, as
+the talk was mostly about the speaker's ideology. If this does not interest you,
+I'd suggest you skip the [Discourse Without Drama](#discourse-without-drama)
+section, and head straight to the [European Perl Mongers Organiser's Forum
+2018](#european-perl-mongers-organiser-s-forum-2018).
+{{< / admonition >}}
+
+## Discourse Without Drama
+
+This was the first talk, and the only talk available at this timeslot. I am
+personally very much against the diversity ideology, and must admit I am
+skeptical of such presentations from the get-go. Nonetheless, I did stay until
+the end and tried to give it a fair shot. However, I cannot sit idle while she
+tries to force her ideology on this community I care very deeply about.
+
+{{< admonition title="note" >}}
+I am not against the concept of diversity, I wholly support the idea of equal
+opportunities. What I do not accept is the idea of equal outcome, or forced
+diversity based on physical traits. This is what I refer to with "the diversity
+ideology". I also don't think anyone has a right not to be offended, as this is
+impossible to achieve in the real world.
+{{< / admonition >}}
+
+One of the things that stood out to me is that the speaker tells us not to use
+logical fallacies to condemn her ideology. This on itself I can easily agree
+with. However, this should go both ways: we should also not use logical
+fallacies to promote her ideology. Most notably, she pointed out the
+[_argumentum ad populum_](https://en.wikipedia.org/wiki/Argumentum_ad_populum).
+This basically means that just because a lot of people do or say something,
+doesn't make it right. And this applies to the idea that we need to push the
+diversity ideology in the Perl community as well. Try to bring facts and
+statistics to show that this ideology will actually improve the community in
+the long term. I've personally not seen any community improve with increasingly
+harsh punishments for increasingly minor offenses.
+
+Another thing which slightly bothered me is the useless spin into radical
+feminist ideology, which to me seems very off-topic for a Perl conference.
+We're not at a political rally, and these kinds of remarks have been very
+divisive in all sorts of other environments already. I'd rather not bring this
+kind of behaviour to a community which I have loved for being so incredibly
+friendly without needing special rules and regulations for it.
+
+Next, a point is raised that people should *not* grow a thicker skin. Instead,
+people should get softer hearts. While I can get behind the latter part, I
+have to disagree with the former. Reality shows that communications don't
+always go perfectly. This is even more true in a community that exists mostly
+in the digital space. Context is often lost here, and that can lead to
+situations where someone may feel attacked even if this was not the intention
+at all. I can safely say I've been in many situations where my comments were
+perceived as an attack when they were not ment to be.
+
+People need to be able to handle some criticism, and sometimes you'll just have
+to assume good faith from the other party. Telling people they should never
+have to consider context and have a right not to be offended fosters an
+environment in which people will be afraid to give genuine, valid feedback.
+
+She seemed very much in favour of an overly broad code of conduct as well, of
+which I am also a strong opponent. There are various articles online, such as
+[this one](https://shiromarieke.github.io/coc.html), which show that just
+slapping a generic, vague code of conduct to a community isn't going to solve
+the issue of trolls or harmful behaviour. There's [another great
+article](http://quillette.com/2017/07/18/neurodiversity-case-free-speech/) that
+I was pointed towards that highlight how this attempt to censor people for the
+sake of not offending anyone can effectively halt creativity and the exchange of
+ideas. There was also an interesting quote written on one of the walls of the
+venue:
+
+{{< quote attribution="Oscar Romero" >}}
+Aspire not to have more, but to be more...
+{{< / quote >}}
+
+Don't try to add meaningless documents such as a code of conduct, which more
+often than not hurts a community instead of improving it. Try to be a better
+person that tries to solve actual issues without harming the community at large.
+Be the adult in the conversation that can take an insult, and still be kind.
+[Remember to hug the
+trolls](https://rakudo.party/post/On-Troll-Hugging-Hole-Digging-and-Improving-Open-Source-Communities#hug2:feedthehandthatbitesyou),
+and eventually they will hug you back.
+
+## European Perl Mongers Organiser's Forum 2018
The Perl community isn't big nowadays, however, the Perl 6 language also offers
a lot of concepts which are very well suited for modern programming. Sadly, if
@@ -70,10 +134,10 @@ server could also be built as a Perl 6 module, possibly named
`CPAN::Tester::ResultsServer`. This would make setting up an environment
similar to CPAN testers for Perl 5 quite easy for Perl 6.
-== Perl 6 in Real Life $Work
+## Perl 6 in Real Life $Work
The speaker shows the perfect use case for
-https://docs.perl6.org/language/grammars[Perl 6 grammars], advanced yet
+[Perl 6 grammars](https://docs.perl6.org/language/grammars), advanced yet
readable parsing of text and performing actions with the results. It's an
interesting talk, showcasing some nifty grammar constructs. The best part of
this is that it actually runs in production, where it parses over 700 files,
@@ -84,7 +148,7 @@ It might be interesting to run this application of grammars on every Perl 6
release to gather more information on the speed improvements of Perl 6, much
like Tux's `Text::CSV` runs.
-== Releasing a Perl 6 Module
+## Releasing a Perl 6 Module
The speaker starts off with detailing the platform which most Perl 6 modules
use to host their code repository, GitHub. He also touched upon automated
@@ -115,7 +179,7 @@ rendering it unusable by others. I would strongly recommend people not to use
S22 when trying to figure out what they can or cannot do with their
`META6.json`.
-== How to become CPAN contributor?
+## How to become CPAN contributor?
Submitting a pull request (or more correctly named, merge request) to a
repository is possibly the most straightforward way to help out other projects.
@@ -131,11 +195,7 @@ can work out your contribution and see if you can get it merged into the main
project.
The speaker also lists a couple of ways to get started with contributing to
-modules. One thing I missed in particular was the Squashathons
-footnote:[A Squashathon is like a hackathon, except everyone in the world is
-invited, and you can help out over the Internet, staying in your own home. Of
-course, you can still meet up with other developers and make it a social
-gathering in the real world as well!] for Perl 6.
+modules. One thing I missed in particular was the Squashathons[^1] for Perl 6.
These generally offer a good entry point to help out with the language's
development and the ecosystem's maintainance.
@@ -148,7 +208,7 @@ mature and professional, you can simply ask for clarification. If you feel the
person remains hostile towards you, walk away. There's plenty of other projects
that would love your contributions!
-== Conference Organizers & European Perl Mongers Organiser's Forum 2018 BoF
+## Conference Organizers & European Perl Mongers Organiser's Forum 2018 BoF
Well, that's certainly a mouthful for a heading, and it even contains an
abbreviation! This event was not a presentation, but a platform to exchange
@@ -181,10 +241,10 @@ Personally, I'd like to see something like this to be written in Perl 6. This
way, it could also be used as a showcase project for the Perl 6 programming
language.
-== Writing a Perl 6 Module
+## Writing a Perl 6 Module
Perl 6 has this very neat feature called
-https://docs.perl6.org/language/typesystem#index-entry-subset-subset[subsets].
+[subsets](https://docs.perl6.org/language/typesystem#index-entry-subset-subset).
These can be used to make your own types with very little effort, which can
help tremendously to keep your code clean and concise. There are two arguments
I have in favour of subsets that the speaker did not touch upon.
@@ -195,9 +255,9 @@ signature, and the check fails, you'll get an error that there was no signature
that matched `where { ... }`.
Secondly, if you want to use abstract methods, you can't really use a `where`.
-https://stackoverflow.com/questions/51570655/how-to-use-abstract-multi-methods-containing-a-where[I've
-asked a question about this on Stack Overflow], which has the details as to why
-this doesn't work the way you might expect.
+[I'ev asked a question about this on Stack
+Overflow](https://stackoverflow.com/questions/51570655/how-to-use-abstract-multi-methods-containing-a-where),
+which has the details as to why this doesn't work the way you might expect.
Next, there's some cool things about operators in Perl 6. There are many of
these available by default, and it's _very_ easy to add new ones yourself as
@@ -212,25 +272,24 @@ I have some comments on the `Math::Matrix` module itself as well, based on
slides shown in the presentiation. The first thing I noticed is that there's a
`norm` method using a `where` clause when it's not needed:
-[source,perl6]
-----
+```raku
method norm (Str $which where * eq 'row-sum')
-----
+```
This can be written instead as:
-[source,perl6]
-----
+```raku
method norm ('row-sum')
-----
+```
-This is shorter and clearer, and you'll get better feedback from the compiler
-as well. I https://github.com/pierre-vigier/Perl6-Math-Matrix/pull/49[submitted
-a pull request on the GitHub repository] in an attempt to improve this, which
-got merged! The speaker was not aware it could be done in this manner, so I'm
-proud I got to teach him something right after he did his presentation.
+This is shorter and clearer, and you'll get better feedback from the compiler as
+well. I [submitted a pull request on the GitHub
+repository](https://github.com/pierre-vigier/Perl6-Math-Matrix/pull/49) in an
+attempt to improve this, which got merged! The speaker was not aware it could be
+done in this manner, so I'm proud I got to teach him something right after he
+did his presentation.
-== Winding down
+## Winding down
I've had a great time at the Perl conference, spoke to many people with whom
I've had some great discussions. I got to meet and personally thank a number of
@@ -238,3 +297,8 @@ people who've helped me out over the past year as well.
A big thank you to all the people who made this conference possible, and I hope
to see you all again in Riga!
+
+[^1]: A Squashathon is like a hackathon, except everyone in the world is
+invited, and you can help out over the Internet, staying in your own home. Of
+course, you can still meet up with other developers and make it a social
+gathering in the real world as well!
diff --git a/src/_posts/2018-09-04-setting-up-pgp-with-a-yubikey.adoc b/content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md
index 4b7cee0..36e0ef6 100644
--- a/src/_posts/2018-09-04-setting-up-pgp-with-a-yubikey.adoc
+++ b/content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md
@@ -1,12 +1,12 @@
---
+title: Setting up PGP with a Yubikey
date: 2018-09-04
-tags: Security YubiKey PGP GPG
-description: >
- An introduction to decent security using the Yubikey as your physical
- security card.
+tags:
+- GPG
+- PGP
+- Security
+- YubiKey
---
-= Setting up PGP with a Yubikey
-:toc: preamble
I've recently started a job where I am required to have above-average security
practices in place on my machine. I already had some standard security in
@@ -19,13 +19,12 @@ In this blogpost, I will detail how I set up my security policies in the hopes
it will be able to help out other people looking to improve their security, and
to get feedback to improve my set up as well.
-[NOTE]
-====
+{{< admonition title="note" >}}
I am using the Yubikey 4. If you're using another version, some steps may
differ.
-====
+{{< / admonition >}}
-== Installing required software
+## Installing required software
You'll need some software to set all of this up. Depending on your
distribution, some of it might already be installed. Everything not installed
@@ -41,13 +40,13 @@ installing `pcsc-lite`, which you can do by simply killing the existing
To securely remove the temporary data we need, you should make sure you have
`secure-delete` available on your system as well.
-== Personalizing the Yubikey
+## Personalizing the Yubikey
The Yubikey can be personalized. Some of this personalization is completely
optional, such as setting personal information. However, setting new PIN codes
is strongly advised, as the default values are publicly known.
-=== PIN codes
+### PIN codes
The PIN codes are short combinations of numbers, letters and symbols to grant
permission to write to or retrieve data from the Yubikey. The default value for
@@ -55,46 +54,42 @@ the user PIN is `123456`. The admin PIN is `12345678` by default. These should
be changed, as they're publicly known and allow the usage of your private keys.
To change these, use the `gpg` program and enter admin mode:
-[source]
-----
+```txt
gpg --card-edit
gpg/card> admin
Admin commands are allowed
-----
+```
You'll notice it immediately says that admin commands are now allowed to be
used. The admin PIN (`12345678`) will be asked whenever an admin command is
executed. It will then be stored for this session, so you won't have to enter
it right away. To update the PIN values, run the following commands:
-[source]
-----
+```txt
gpg/card> passwd
gpg/card> 3
-----
+```
This will change the admin PIN first. This PIN is required for managing the
keys and user PIN on the Yubikey. To set the user PIN, pick `1` instead of `3`:
-[source]
-----
+```txt
gpg/card> 1
-----
+```
Once this is done, you can quit the `passwd` submenu using `q`:
-[source]
-----
+```txt
gpg/card> q
-----
+```
You may have noticed we skipped the reset code. Resetting the device will wipe
existing keys, so it's not a serious risk to keep this at the default. The
private keys will be backed up to an encrypted USB drive, so we can always
retrieve them and put them back on the Yubikey if ever needed.
-=== Personal information
+### Personal information
The personal information is optional, but could be used by a friendly person to
find out who a found Yubikey belongs to. They can contact the owner, and send
@@ -102,10 +97,9 @@ the key back. You can set as many of the personally identifying fields as you
want. If you're interested in setting this information, plug in your Yubikey
and edit the card information with `gpg`:
-[source]
-----
+```txt
gpg --card-edit
-----
+```
Once you're back in the GPG shell, you can update your personal information.
There are 5 attributes that you can set in this way:
@@ -119,30 +113,28 @@ There are 5 attributes that you can set in this way:
Each of these attributes can be updated by running the command in the GPG
shell. For instance, to update your real name, run the following:
-[source]
-----
+```txt
gpg/card> name
-----
+```
You do not need to explicitly save once you're done. You can run `quit` to quit
the GPG shell and return to your regular shell.
-== Creating PGP keys
+## Creating PGP keys
To create the PGP keys, we'll create a temporary directory which will function
as our working directory to store the keys in. This way you can't accidentally
break existing keys if you have them, and ensure that the private keys don't
accidentally linger on in your filesystem.
-=== Preparing a clean environment
+### Preparing a clean environment
To create such a temporary directory, we'll use `mktemp`, and store the result
in an environment variable so we can easily re-use it:
-[source,sh]
-----
+```sh
export GNUPGHOME="$(mktemp -d)"
-----
+```
Now you can switch to that directory using `cd "$GNUPGHOME"`. Additionally,
`$GNUPGHOME` is also the directory `gpg` uses as its working directory, if it
@@ -150,8 +142,7 @@ is set. This means you can use a temporary custom configuration for `gpg` as
well, without it affecting your normal setup. The following configuration is
recommended to set in `$GNUPGHOME/gpg.conf` before starting:
-[source,conf]
-----
+```conf
use-agent
charset utf-8
no-comments
@@ -159,12 +150,12 @@ keyid-format 0xlong
list-options show-uid-validity
verify-options show-uid-validity
with-fingerprint
-----
+```
If you have a `gpg-agent` running, it is recommended to stop it before
continuing with `killall gpg-agent`.
-=== Creating the master key
+### Creating the master key
For our master key, we'll go for a 4096 bytes RSA key. 2048 would be plenty as
well, if you want the generation to be a tad quicker. `gpg` will ask you a
@@ -174,10 +165,9 @@ addresses, for instance.
Start the key generation process with `gpg`:
-[source]
-----
+```txt
gpg --full-generate-key
-----
+```
When asked what kind of key you want, choose `4` (RSA (sign only)). Next is the
key size, which should be `4096`.
@@ -210,15 +200,14 @@ Take note of the line starting with `pub`. It shows that the key is an
throughout the rest of this post. For convenience, you can store this ID in
a variable, and just refer to the variable when you need it's value again:
-[source,sh]
-----
+```sh
export KEYID=0x27F53A16486878C7
-----
+```
This post will use the `$KEYID` variable from now on, to make it easier to
follow.
-=== Creating a revocation certificate
+### Creating a revocation certificate
The revocation certificate can be used to invalidate your newly created key.
You should store it seperately from the private master key, preferably printed
@@ -227,10 +216,9 @@ printing it as a QR code.
To create the certificate, run the following:
-[source]
-----
+```txt
gpg --gen-revoke $KEYID > $GNUPGHOME/revoke.txt
-----
+```
This will prompt you to specify a reason, for which you'll want to use `1`.
This way you can easily revoke the key's validity if you ever lose it. If you
@@ -239,7 +227,7 @@ generate a new revocation certificate for that specific purpose. You don't have
to supply an additional description, so just hit enter. A revocation
certificate will be written to `$GNUPGHOME/revoke.txt`.
-=== Creating the subkeys
+### Creating the subkeys
Now that you have your master key and the ability to revoke it in case anything
goes wrong in the future, it's time to create a couple of subkeys which can be
@@ -270,20 +258,19 @@ key, and 3 `ssb` keys, which are the subkeys. One line should end with `[S]`,
one with `[E]` and one with `[A]`. These denote the capabilities of the
subkeys, _Sign_, _Encrypt_ and _Authenticate_, respectively.
-=== Export the keys
+### Export the keys
Now that you have your keys generated, you should export them, allowing you to
easily import them in another environment in case you ever need to generate
more keys, invalidate some keys, or extend the validity of the keys in case you
set an expiry date. This can be done with the following commands:
-[source,sh]
-----
+```txt
gpg --armor --export-secret-keys $KEYID > masterkey.asc
gpg --armor --export-secret-subkeys $KEYID > subkeys.asc
-----
+```
-== Creating a backup USB
+## Creating a backup USB
For the backup of the private keys, I'm using an encrypted USB device. You can
also opt to print the keys to paper, and retype them if you ever need them. Or
@@ -291,23 +278,21 @@ print a QR code that you can scan. But for convenience sake, I went with a USB
device. I encrypted it, and stored it in a safe and sealed location, so it's
easy to detect unwanted attempted access.
-=== Encrypting the USB
+### Encrypting the USB
For the encryption, I went with full device encryption using LUKS. You will
need the `cryptsetup` utility to apply the encryption, and to unlock the drive.
You can find out the device name from `dmesg` or `lsblk`. Once you know it,
encrypt the drive with the `luksFormat` subcommand.
-[WARNING]
-====
+{{< admonition title="warning" >}}
Using the wrong name for the device can irrecoverably destroy data from another
drive!
-====
+{{< / admonition >}}
-[source,sh]
-----
+```txt
cryptsetup luksFormat /dev/sdb
-----
+```
It will prompt you whether you want to continue, and ask twice for a passphrase
to ensure it is correct. Make sure you don't forget the passphrase, or you'll
@@ -315,50 +300,45 @@ lose access to your backup keys.
Once it has been encrypted, unlock the device.
-[source,sh]
-----
+```txt
cryptsetup luksOpen /dev/sdb crypt
-----
+```
This will open the device as `/dev/mapper/crypt`. Format it with your favourite
filesystem. I used `ext4`.
-[source,sh]
-----
+```txt
mkfs.ext4 /dev/mapper/crypt
-----
+```
Once it has been formatted, you can mount it as a regular device.
-[source,sh]
-----
+```txt
mount /dev/mapper/crypt /mnt/usb
-----
+```
-=== Copying the keys
+### Copying the keys
Copying the keys is as straightforward as copying other files. You can use
`$GNUPGHOME` to target the source directory.
-[source,sh]
-----
+```txt
cp -arv "$GNUPGHOME"/* /mnt/usb/.
-----
+```
Once the files are copied, you can unmount the drive, lock it and unplug the
USB.
-[source,sh]
-----
+```txt
sync
umount /mnt/usb
cryptsetup luksClose crypt
-----
+```
Store the USB in a safe location, because these private keys can give someone
full control of your identity.
-== Storing the private keys on the Yubikey
+## Storing the private keys on the Yubikey
The Yubikey has key slots for encryption, signing and authentication. These
need to be set individually, which can be done using `gpg`. First, you need to
@@ -366,8 +346,7 @@ select a key using the `key` command, then store it on the card using
`keytocard` and select a slot to store it in, then finally deselect the key by
using the `key` command again.
-[source]
-----
+```txt
gpg --edit-key $KEYID
gpg> key 1
@@ -385,27 +364,27 @@ gpg> keytocard
Your selection? 3
gpg> save
-----
+```
You can verify whether the keys are available on the Yubikey now using `gpg
--card-status`. It will show the key fingerprints for the `Signature key`,
`Encryption key` and `Authentication key`.
-=== Sharing your public key
+### Sharing your public key
-You can share your public keys in many ways. Mine is hosted link:/pubkey.txt[on
-my own site], for instance. There are also https://sks-keyservers.net/[public
-keyservers] on which you can upload your keys. `gpg` has the `--send-keys` and
-`--recv-keys` switches to interact with these public keyservers. For ease of
-use, I would recommend uploading them to a public keyserver, so that other
-people can easily import it. For instance, my key can be imported using `gpg`:
+You can share your public keys in many ways. Mine is hosted [on my own
+site](/pubkey.txt), for instance. There are also [public
+keyservers](https://sks-keyservers.net/) on which you can upload your keys.
+`gpg` has the `--send-keys` and `--recv-keys` switches to interact with these
+public keyservers. For ease of use, I would recommend uploading them to a public
+keyserver, so that other people can easily import it. For instance, my key can
+be imported using `gpg`:
-[source]
-----
+```txt
gpg --recv-keys 0x7A6AC285E2D98827
-----
+```
-== Clean up
+## Clean up
The keys are on the Yubikey, and you probably do not want to leave traces on
your local system of these new keys, so you should clean up the `$GNUPGHOME`
@@ -413,28 +392,25 @@ directory. There's a utility for securely removing a directory with all its
contents, called `secure-delete`, which provides the `srm` program. You can use
it just like the regular `rm` on the temporary directory.
-[source,sh]
-----
+```txt
srm -r "$GNUPGHOME"
-----
+```
You can also `unset` the `$GNUPGHOME` variable at this point, so `gpg` will use
it's default configuration again.
-[source,sh]
-----
+```txt
unset GNUPGHOME
-----
+```
-== Configure GPG
+## Configure GPG
Finally, you have your keys on the Yubikey and the traces that might have been
left on your device are wiped clean. Now you should configure `gpg` for regular
use as well, however, this is completely optional. All this configuration does
is ensure you have good defaults for the current day and age.
-[source]
-----
+```conf
auto-key-locate keyserver
keyserver hkps://hkps.pool.sks-keyservers.net
keyserver-options no-honor-keyserver-url
@@ -455,9 +431,9 @@ verify-options show-uid-validity
with-fingerprint
use-agent
require-cross-certification
-----
+```
-== Conclusion
+## Conclusion
You now have PGP keys available on your Yubikey. These keys are only available
to your system if the Yubikey is inserted, and the user PIN is given. You can
diff --git a/src/_posts/2018-09-13-hackerrank-solutions-python3-and-perl6-part-1.adoc b/content/posts/2018/2018-09-13-hackerrank-solutions-python3-and-perl6-part-1.md
index 6dd01a6..7272d51 100644
--- a/src/_posts/2018-09-13-hackerrank-solutions-python3-and-perl6-part-1.adoc
+++ b/content/posts/2018/2018-09-13-hackerrank-solutions-python3-and-perl6-part-1.md
@@ -1,75 +1,73 @@
---
-tags: Hackerrank Perl6 Python Python3 Programming Raku
-description: >
- A number of solutions to Hackerrank challenges in both the Python 3 and the
- Perl 6 programming languages. Compare the results and see which language
- works best for you!
+title: "Hackerrank Solutions: Python 3 and Perl 6 (part 1)"
+date: 2018-09-13
+tags:
+- Hackerrank
+- Perl6
+- Python
+- Python3
+- Programming
+- Raku
---
-= Hackerrank solutions: Python 3 and Perl 6 (part 1)
-:toc: preamble
I recently started at a new company, for which I will have to write Python 3
code. To make sure I still know how to do basic stuff in Python, I started to
-work on some https://www.hackerrank.com/[Hackerrank challenges]. In this post,
+work on some [Hackerrank challenges](https://www.hackerrank.com/). In this post,
I will show solutions to some challenges to show the differences. I hope that I
can show that Perl doesn't have to be the "write only" language that many
people make it out to be.
-[NOTE]
-====
+{{< admonition title="note" >}}
I am _much_ more proficient in the Perl 6 programming language than in Python
(2 or 3), so I might not always use the most optimal solutions in the Python
variants. Suggestions are welcome via email, though I most likely won't update
this post with better solutions. I ofcourse also welcome feedback on the Perl 6
solutions!
-====
+{{< / admonition >}}
-== Challenges
+## Challenges
-The challenges covered in this post are the
-https://www.hackerrank.com/domains/algorithms?filters%5Bsubdomains%5D%5B%5D=warmup[warmup
-challenges] you are recommended to solve when you make a new account. The code
-around the function I'm expected to solve won't be included, as this should be
-irrelevant (for now). Additionally, I may rename the sub to conform to
-https://en.wikipedia.org/wiki/Letter_case#Special_case_styles[kebab-case], as
+The challenges covered in this post are the [warmup
+challenges](https://www.hackerrank.com/domains/algorithms?filters%5Bsubdomains%5D%5B%5D=warmup)
+you are recommended to solve when you make a new account. The code around the
+function I'm expected to solve won't be included, as this should be irrelevant
+(for now). Additionally, I may rename the sub to conform to
+[kebab-case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles), as
this is more readable (in my opinion), and allowed in Perl 6.
-=== Solve Me First
+### Solve Me First
This challenge is just a very simple example to introduce how the site works.
It required me to make a simple `a + b` function.
-[source,py3]
-----
+```python3
def solveMeFirst(a,b):
return a+b
-----
+```
The Perl 6 variant isn't going to very different here.
-[source,perl6]
-----
+```raku
sub solve-me-first ($a, $b) {
$a + $b
}
-----
+```
For those not familiar with Perl 6, the `$` in front of the variable names is
-called a https://docs.perl6.org/language/glossary#index-entry-Sigil[Sigil], and
-it signals that the variable contains only a single value.
+called a [Sigil](https://docs.perl6.org/language/glossary#index-entry-Sigil),
+and it signals that the variable contains only a single value.
You may have noticed that there's also no `return` in the Perl 6 variant of
this example. In Perl 6, the last statement in a block is also the implicit
return value (just like in Perl 5 or Ruby).
-=== Simple Array Sum
+### Simple Array Sum
For this challenge I had to write a function that would return the sum of a
list of values. Naturally, I wanted to use a `reduce` function, but Python 3
does not support these. So I wrote it with a `for` loop instead.
-[source,py3]
-----
+```python3
def simpleArraySum(ar):
sum = 0
@@ -77,41 +75,38 @@ def simpleArraySum(ar):
sum += i
return sum
-----
+```
Perl 6 does have a `reduce` function, so I would use that to solve the problem
here.
-[source,perl6]
-----
+```raku
sub simple-array-sum (@ar) {
@ar.reduce(sub ($a, $b) { $a + $b })
}
-----
+```
Here you can see a different sigil for `@ar`. The `@` sigil denotes a list of
scalars in Perl 6. In most other languages this would simply be an array.
-This code can be written even shorter, however. Perl 6 has
-https://docs.perl6.org/language/operators#index-entry-%5B%2B%5D_%28reduction_metaoperators%29[reduction
-meta-operators]. This allows you to put an operator between brackets, like
-`[+]`, to apply a certain operator as a reduce function.
+This code can be written even shorter, however. Perl 6 has [reduction
+meta-operators](https://docs.perl6.org/language/operators#index-entry-%5B%2B%5D_%28reduction_metaoperators%29).
+This allows you to put an operator between brackets, like `[+]`, to apply a
+certain operator as a reduce function.
-[source,perl6]
-----
+```raku
sub simple-array-sum (@ar) {
[+] @ar
}
-----
+```
-[NOTE]
-====
+{{< admonition title="note" >}}
After publishing this post I have learned that both Python 3 and Perl 6 have a
`.sum` function that can also be called on the array, simplifying the code in
both languages.
-====
+{{< / admonition >}}
-=== Compare the Triplets
+### Compare the Triplets
This challenge provides you with 2 lists of 3 elements each. The lists should
be compared to one another, and a "score" should be kept. For each index, if
@@ -120,8 +115,7 @@ incremented. Similarly, if the second list contains a larger number on that
index, the second list's score must be incremented. If the values are equal, do
nothing.
-[source,py3]
-----
+```python3
def compareTriplets(a, b):
scores = [0, 0]
@@ -133,13 +127,12 @@ def compareTriplets(a, b):
scores[1] += 1
return scores
-----
+```
I learned that Python 3 has no `++` operator to increment a value by 1, so I
had to use `+= 1` instead.
-[source,perl6]
-----
+```raku
sub compare-triplets (@a, @b) {
my @scores = [0, 0];
@@ -148,31 +141,29 @@ sub compare-triplets (@a, @b) {
@scores[1]++ if @a[$_] < @b[$_];
}
}
-----
+```
In Perl 6, the `^3` notation simply means a range from 0 to 3, non-inclusive,
so `0`, `1`, `2`, meaning it will loop 3 times. The `$_` is called the
-__topic__, and in a `for` loop it is the current element of the iteration.
+_topic_, and in a `for` loop it is the current element of the iteration.
Both of these loops could use a `continue` (or `next` in Perl 6) to skip the
second `if` in case the first `if` was true, but for readability I chose not
to.
-[NOTE]
-====
+{{< admonition title="note" >}}
After publishing this post I learned that Python 3 also supports the inline if
syntax, just like Perl 6, so I could've used this in Python 3 as well.
-====
+{{< / admonition >}}
-=== A Very Big Sum
+### A Very Big Sum
In this challenge, you need to write the function body for `aVeryBigSum`, which
gets an array of integers, and has to return the sum of this array. Both Python
3 and Perl 6 handle the large integers transparently for you, so I was able to
use the same code as I used for the simple array sum challenge.
-[source,py3]
-----
+```python3
def aVeryBigSum(ar):
sum = 0
@@ -180,18 +171,17 @@ def aVeryBigSum(ar):
sum += i
return sum
-----
+```
And for Perl 6 using the `[+]` reduce meta-operation.
-[source,perl6]
-----
+```raku
sub a-very-big-sum (@ar) {
[+] @ar
}
-----
+```
-=== Plus Minus
+### Plus Minus
The next challenge gives a list of numbers, and wants you to return the
fractions of its elements which are positive, negative or zero. The fractions
@@ -199,8 +189,7 @@ should be rounded down to 6 decimals. I made a counter just like in the
*Compare the Triplets* challenge, and calculated the fractions and rounded them
at the end.
-[source,py3]
-----
+```python3
def plusMinus(arr):
counters = [0, 0, 0]
@@ -217,13 +206,12 @@ def plusMinus(arr):
for i in counters:
print("%.6f" % (i / len(arr)))
-----
+```
For the Perl 6 solution, I went for a `given/when`, `map` and the `fmt`
function to format the fractions.
-[source,perl6]
-----
+```raku
sub plus-minus (@arr) {
my @counters = [0, 0, 0];
@@ -237,24 +225,24 @@ sub plus-minus (@arr) {
@counters.map({ $_.fmt("%.6f").say });
}
-----
+```
You may notice a number of statements do not have a terminating `;` at the end.
In Perl 6, this is not needed if it's the last statement in a block (any code
surrounded by a `{` and `}`.
The `given/when` construct is similar to a `switch/case` found in other
-languages (but not Python, sadly), but uses the
-https://docs.perl6.org/language/operators#index-entry-smartmatch_operator[smartmatch
-operator] implicitly to check if the statements given to `when` are `True`. The
-`*` is the https://docs.perl6.org/type/Whatever[Whatever operator], which in
-this case will get the value of `$i`.
+languages (but not Python, sadly), but uses the [Smartmatch
+operator](https://docs.perl6.org/language/operators#index-entry-smartmatch_operator)
+implicitly to check if the statements given to `when` are `True`. The `*` is the
+[Whatever operator](https://docs.perl6.org/type/Whatever), which in this case
+will get the value of `$i`.
Lastly, he `$_` in the `map` function is similar to inside a `for` loop,
it's the current element. Since the code given to `map` is inside a block,
there's no need for a `;` after `say` either.
-=== Staircase
+### Staircase
This challenge gives you an integer 𝓃, and you're tasked with "drawing" a
staircase that is 𝓃 high, and 𝓃 wide at the base. The staircase must be made
@@ -263,8 +251,7 @@ using `#` characters, and for the spacing you must use regular spaces.
It seems that in Python, you _must_ specify the `i in` part oft the `for i in
range`. Since I don't really care for the value, I assigned it to `_`.
-[source,py3]
-----
+```python3
def staircase(n):
for i in range(1, n + 1):
for _ in range(n - i):
@@ -274,15 +261,14 @@ def staircase(n):
print("#", end="")
print("")
-----
+```
In Perl 6, there's also a `print` function, which is like `say`, but does not
append a `\n` at the end of the string. The `for` loop in Perl 6 allows for
just a range to operate as expected. The `..` operator creates a range from the
left-hand side up to the right hand side, inclusive.
-[source,perl6]
-----
+```raku
sub staircase ($n) {
for 1..$n -> $i {
print(" ") for 0..($n - $i);
@@ -290,9 +276,9 @@ sub staircase ($n) {
print("\n");
}
}
-----
+```
-=== Mini-Maxi Sum
+### Mini-Maxi Sum
Here you will be given 5 integers, and have to calculate the minimum and
maximum values that can be calculated using only 4 of them.
@@ -301,8 +287,7 @@ I sort the array, and iterate over the first 4 values to calculate the sum and
print it. I then do the same but sort it in reverse for the sum of the 4
highest values.
-[source,py3]
-----
+```python3
def miniMaxSum(arr):
arr.sort()
sum = 0
@@ -319,7 +304,7 @@ def miniMaxSum(arr):
sum += arr[i]
print(str(sum))
-----
+```
Perl 6 has immutable lists, so calling `sort` on them will return a new list
which has been sorted. I can call `reverse` on that list to get the highest
@@ -328,16 +313,15 @@ functional way. You've already seen the meta-reduce operator `[+]`, which will
get me the sum of the 4 elements I got from `head`. I wrap the calculation in
parenthesis so I can call `print` on the result immediately.
-[source,perl6]
-----
+```raku
sub mini-maxi-sum (@arr) {
([+] @arr.sort.head(4)).print;
print(" ");
([+] @arr.sort.reverse.head(4)).print;
}
-----
+```
-=== Birthday Cake Candles
+### Birthday Cake Candles
In this challenge, you're given a list of numbers. You must find the highest
number in the list, and return how often that number occurs in the list.
@@ -346,8 +330,7 @@ It's fairly straightforward, I keep track of the current largest value as
`size`, and a `count` that I reset whenever I find a larger value than I
currently have.
-[source,py3]
-----
+```python3
def birthdayCakeCandles(ar):
size = 0
count = 0
@@ -361,13 +344,12 @@ def birthdayCakeCandles(ar):
count += 1
return count
-----
+```
The Perl 6 variant does not differ in how it solves the problem, apart from
having a very different syntax of course.
-[source,perl6]
-----
+```raku
sub birthday-cake-candles (@ar) {
my ($size, $count) = (0, 0);
@@ -382,16 +364,15 @@ sub birthday-cake-candles (@ar) {
$count;
}
-----
+```
-[NOTE]
-====
+{{< admonition title="note" >}}
On IRC, someone showed me a clean solution in Python 3: `return
ar.count(max(ar))`. This feels like a much cleaner solution than what I had
created.
-====
+{{< / admonition >}}
-=== Time Conversion
+### Time Conversion
This is the final challenge of this section on Hackerrank, and also this post.
You're given a timestamp in 12-hour AM/PM format, and have to convert it to a
@@ -405,8 +386,7 @@ set the hours to 0 if it's set to 12, and add 12 hours if the timestamp was
post meridiem. Finally, I convert the hours back to a string with leading
zeroes, and join all the parts together to form a timestamp again.
-[source,py3]
-----
+```python3
def timeConversion(s):
meridiem = s[-2:]
hours = int(s[:2])
@@ -419,18 +399,17 @@ def timeConversion(s):
hours += 12
return ("%02d:%s" % (hours, rest))
-----
+```
The Perl 6 solution again doesn't differ much from the Python solution in terms
of the logic it's using to get the result. The biggest difference is that in
Perl 6, strings can't be accessed as lists, so I use the `substr` method to
extract the parts that I want. The first one starts at `*-2`, which means 2
places before the end. The others get a
-https://docs.perl6.org/type/Range[`Range`] as argument, and will get the
+[`Range`](https://docs.perl6.org/type/Range) as argument, and will get the
characters that exist in that range.
-[source,perl6]
-----
+```raku
sub time-conversion ($s) {
my $meridiem = $s.substr(*-2);
my $hours = $s.substr(0..2).Int;
@@ -441,16 +420,16 @@ sub time-conversion ($s) {
sprintf("%02d:%s", $hours, $rest);
}
-----
+```
The `.Int` method converts the `Str` object into an `Int` object, so we can
-perform calculations on it. The `eq` operator checks specifically for
-https://docs.perl6.org/routine/eq[__string equality__]. Since Perl 6 is a
-https://en.wikipedia.org/wiki/Gradual_typing[gradually typed programming
-language], there's a dedicated operator to ensure that you're checking string
-equality correctly.
+perform calculations on it. The `eq` operator checks specifically for [_string
+equality_](https://docs.perl6.org/routine/eq). Since Perl 6 is a [gradually
+typed programming language](https://en.wikipedia.org/wiki/Gradual_typing),
+there's a dedicated operator to ensure that you're checking string equality
+correctly.
-== Wrap-up
+## Wrap-up
These challenges were just the warm-up challenges I was given after creating a
new account and choosing Python as a language to use. I intend to write up more
@@ -461,5 +440,4 @@ This is also the first post in which I have tried this format to show off two
languages side-by-side, and to highlight differences in how you can accomplish
certain (relatively simple) tasks with them. If you have suggestions to improve
this format, do not hesitate to contact me. I am always open for feedback,
-preferably via email. You can find my contact details on the link:/[homepage].
-
+preferably via email. You can find my contact details on the [homepage](/).
diff --git a/content/posts/2018/_index.md b/content/posts/2018/_index.md
new file mode 100644
index 0000000..e1bb4e6
--- /dev/null
+++ b/content/posts/2018/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2018
+---
diff --git a/src/_posts/2019-02-03-how-to-sign-pgp-keys.html b/content/posts/2019/2019-02-03-how-to-sign-pgp-keys.md
index a8a9618..d5f401a 100644
--- a/src/_posts/2019-02-03-how-to-sign-pgp-keys.html
+++ b/content/posts/2019/2019-02-03-how-to-sign-pgp-keys.md
@@ -1,21 +1,18 @@
---
title: How to sign PGP keys
-layout: post
-tags: PGP Tutorial
-description: >
- A small tutorial on how to sign others PGP keys.
+date: 2019-02-03
+tags:
+- PGP
+- Tutorial
---
-{% markdown %}
Having attended [FOSDEM](https://fosdem.org/2019/) last weekend, I have been
asked to help some people out with signing PGP keys. As it is an international
gathering of users and developers of all levels of expertise, it's a great event
to get your key out in to the wild. While helping people out, I figured it might
be even easier next time around to just refer to a small tutorial on my blog
instead.
-{% endmarkdown %}
-{% markdown %}
## Creating a PGP key
The first step to sign keys, is to have a PGP key. If you already have one,
@@ -27,9 +24,7 @@ guiding you through the process without prior knowledge, so you can just get
started with `gpg --generate-key` as well.
[yubikey-pgp-article]: {{ "/post/2018/09/04/setting-up-pgp-with-a-yubikey/#creating-pgp-keys" | prepend: site.baseurl | prepend: site.url }}
-{% endmarkdown %}
-{% markdown %}
## Create key slips
A *key slip* is a small piece of paper containing some basic information about
@@ -42,14 +37,12 @@ possession of their private key again.
A key slip doesn't have to contain much. A key ID, fingerprint, email address and
a name is plenty. For reference, my key slips look as follows:
-{% endmarkdown %}
-{% highlight text %}
+```txt
Patrick Spek <p.spek@tyil.nl> rsa4096/0x7A6AC285E2D98827
1660 F6A2 DFA7 5347 322A 4DC0 7A6A C285 E2D9 8827
-{% endhighlight %}
+```
-{% markdown %}
## Verifying the owner
Before you sign anyone's public key, you should verify that the person is
@@ -59,9 +52,7 @@ constitutes good proof is up to you, but in general people expect at least one
form of government issued identification.
If the person can't verify who they are, you should *not* sign their key!
-{% endmarkdown %}
-{% markdown %}
## Retrieving their key
Once you have verified the person is who they say they are, and you have
@@ -69,42 +60,34 @@ received their key slip containing their key ID, you can look up their key
online. You can let `gpg` do all the work for you in searching and downloading
the key, using the `--search` switch. For instance, to retrieve my key, do the
following:
-{% endmarkdown %}
-{% highlight sh %}
+```txt
gpg --search-keys 0x7A6AC285E2D98827
-{% endhighlight %}
+```
-{% markdown %}
If a result has been found, you are prompted to enter the numbers of the keys
you want to download. Make sure you download the right key, in case multiple
have been found!
After retrieving the key, you can see it in the list of all the keys `gpg` knows
about using `gpg --list-keys`.
-{% endmarkdown %}
-{% markdown %}
## Signing their key
To actually sign their key, and show that you trust that the key belongs to the
person's name attached to it, you can use `gpg --sign-key`:
-{% endmarkdown %}
-{% highlight sh %}
+```txt
gpg --sign-key 0x7A6AC285E2D98827
-{% endhighlight %}
+```
-{% markdown %}
You will be prompted whether you are sure you want to sign. You should answer
this with a single `y` to continue.
After signing it, you'll have signed a PGP key! You can verify this by looking
at the signatures on a given key with `--list-sigs 0x7A6AC285E2D98827`. This should
contain your name and key ID.
-{% endmarkdown %}
-{% markdown %}
## Exchanging the signed key
While you could publish the updated public key with your signature on it, you
@@ -115,13 +98,11 @@ actually own the private key as well, without ever asking them explicitly to
show you their private key.
To export the public key, use `--export`:
-{% endmarkdown %}
-{% highlight sh %}
+```txt
gpg --armor --export 0x7A6AC285E2D98827 > pubkey-tyil.asc
-{% endhighlight %}
+```
-{% markdown %}
The `--armor` option is used to export the key as base64, instead of binary
data.
@@ -136,20 +117,16 @@ you don't trust your email client to do it right).
You can use the `--encrypt` option for this, and add a `--recipient` to encrypt
it for a specific key.
-{% endmarkdown %}
-{% highlight sh %}
+```txt
gpg --encrypt --recipient 0x7A6AC285E2D98827 < pubkey-tyil.asc > pubkey-tyil.pgp
-{% endhighlight %}
+```
-{% markdown %}
Now you can use this encrypted key file and share it with the owner of the key.
If the person you send it to really is the owner of the key, they can use the
private key to decrypt the file, import it with `gpg --import` and then publish
it with `gpg --send-keys`
-{% endmarkdown %}
-{% markdown %}
## Winding down
Once all this is done, other people should have sent you your signed pubkey as
@@ -162,4 +139,3 @@ encrypt with your public key can only be read by you.
With this [trust](https://en.wikipedia.org/wiki/Web_of_trust), you can make
communication and data exchange in general more secure.
-{% endmarkdown %}
diff --git a/src/_posts/2019-04-11-perl6-nightly-docker-images.html b/content/posts/2019/2019-04-11-perl6-nightly-docker-images.md
index 78c868e..61b54f5 100644
--- a/src/_posts/2019-04-11-perl6-nightly-docker-images.html
+++ b/content/posts/2019/2019-04-11-perl6-nightly-docker-images.md
@@ -1,13 +1,12 @@
---
title: Perl 6 nightly Docker images
-layout: post
-tags: Perl6 Docker Raku
-description: >
- An overview of my work on nightly Perl 6 Docker images, and a few examples
- on how I'm using them.
+date: 2019-04-11
+tags:
+- Perl6
+- Docker
+- Raku
---
-{% markdown %}
Due to the slow release of Rakudo Star (which actually did release a new
version last month), I had set out to make Docker images for personal use based
on the regular Perl 6 releases. But, as I discovered some [memory related
@@ -16,16 +15,12 @@ some possible fixes](https://github.com/MoarVM/MoarVM/pull/1072), I changed my
mind to make them nightlies based on the `master` branches of all related
projects instead. This way I could get fixes faster, and help testing when
needed.
-{% endmarkdown %}
-{% markdown %}
These nightlies are now up and running, available on [Docker
Hub](https://hub.docker.com/r/tyil/perl6) for anyone to use! You can also find
[the Dockerfiles I'm using on git.tyil.nl](https://git.tyil.nl/docker/perl6),
in case you're interested or have suggestions to further improve the process.
-{% endmarkdown %}
-{% markdown %}
The timing of the (public) release of these images could have been better,
though. About two weeks ago, other nightlies were released as well, by Tony
O'Dell, as has been noted in the [Perl 6 Weekly
@@ -34,9 +29,7 @@ greatly appreciate his efforts, I was not going to just abandon all the work
I've put into my images. Instead I've tried to make smaller images, and provide
different bases than him. Maybe we can eventually learn from each other's images
and improve Docker support for the entire community together.
-{% endmarkdown %}
-{% markdown %}
The easiest thing to work on was providing different bases. For now, this means
I have images with the following four base images:
@@ -49,18 +42,14 @@ This way, people can have more options with regards to using the distribution
tooling that they're more comfortable with. One could also opt to use a more
familiar or better supported base image for development and testing out their
module, and use a smaller image for production releases.
-{% endmarkdown %}
-{% markdown %}
As to the size of the images, Tony's `tonyodell/rakudo-nightly:latest` is about
1.42GB at the time of writing this post. My images range from 43.6MB
(`alpine-latest`) to 165MB (`voidlinux-latest`). Though this is not a
completely fair comparison, as my images have stripped out a lot of the tooling
used (and often required) to build some Perl 6 modules, making them unusable in
their default shape for many projects.
-{% endmarkdown %}
-{% markdown %}
To remedy this particular issue, I've also created *-dev* images. These images
come with a number of additional packages installed to allow `zef` to do its
work to get dependencies installed without requiring end-users to search for
@@ -68,17 +57,14 @@ those packages. This should reduce complexity when using the images for
end-users. If we take the dev images into account when comparing sizes, my
images range from 256MB (`alpine-dev-latest`) to 1.27GB
(`voidlinux-dev-latest`). That's much closer to the `rakudo-nightly` image.
-{% endmarkdown %}
-{% markdown %}
If you're interested in trying these images out, you may be interested in the
way I'm using these images myself as reference. Currently, my [CPAN upload
notifier bot](https://git.tyil.nl/perl6/app-cpan-uploadannouncer-irc) is using
these nightly images in its
[`Dockerfile`](https://git.tyil.nl/perl6/app-cpan-uploadannouncer-irc/src/branch/master/Dockerfile).
-{% endmarkdown %}
-{% highlight dockerfile %}
+```Dockerfile
FROM tyil/perl6:debian-dev-latest as install
RUN apt update && apt install -y libssl-dev uuid-dev
@@ -86,18 +72,16 @@ RUN apt update && apt install -y libssl-dev uuid-dev
COPY META6.json META6.json
RUN zef install --deps-only --/test .
-{% endhighlight %}
+```
-{% markdown %}
As you can see from the `Dockerfile`, I start out by using a `-dev` image, and
name that stage `install`. I'm still contemplating to include `libssl-dev` into
the `-dev` images, as it seems to pop up a lot, but for now, it's not part of
the `-dev` images, so I install it manually. Same goes for `uuid-dev`. Then I
copy in the `META6.json`, and instruct `zef` to install all the dependencies
required.
-{% endmarkdown %}
-{% highlight dockerfile %}
+```Dockerfile
FROM tyil/perl6:debian-latest
ENV PERL6LIB=lib
@@ -116,33 +100,25 @@ RUN mkdir -p /var/docker/meta
RUN date "+%FT%TZ" > /var/docker/meta/build-date
CMD [ "perl6", "bin/bot" ]
-{% endhighlight %}
+```
-{% markdown %}
Then I start a new stage. I set the `$PERL6LIB` environment variable so I don't
have to use `-Ilib` at the end, and set a `WORKDIR` to have a clean directory
to work in. Next, I set up the *runtime dependencies* of the application.
-{% endmarkdown %}
-{% markdown %}
I then continue to copy in the `bin` and `lib` directories, containing the
application itself, and copy over `/usr/local` from the `install` stage.
`/usr/local` is where Perl 6 is installed, and `zef` installs all its
dependencies into. This way, the `-dev` image can be used for building all the
dependencies as needed, and only the finished dependencies end up in the final
image that's going to run in production.
-{% endmarkdown %}
-{% markdown %}
Lastly, I set the build date and time of the image in a file, so the
application can refer to it later on. It is displayed when the IRC bot replies
to a `.bots` command, so I can verify that the running bot is the one I just
built. And finally, the `CMD` instruction runs the application.
-{% endmarkdown %}
-{% markdown %}
I hope this displays how the images can be used for your applications, and the
reasoning as to why I made them the way they are. If you have any suggestions
or issues, feel free to contact me in whatever way suits you best. You can find
some contact details on the homepage of my blog.
-{% endmarkdown %}
diff --git a/src/_posts/2019-07-22-the-powerful-tooling-of-gentoo.html b/content/posts/2019/2019-07-22-the-powerful-tooling-of-gentoo.md
index aa90e80..9d8cff2 100644
--- a/src/_posts/2019-07-22-the-powerful-tooling-of-gentoo.html
+++ b/content/posts/2019/2019-07-22-the-powerful-tooling-of-gentoo.md
@@ -1,29 +1,21 @@
---
-title: The Power(ful Tooling) of Gentoo
-layout: post
-tags: Gentoo
-description: >
- Why do people (like me) love Gentoo so much? Part of it is stability and
- configurability, but there is also an amazing set of tooling available to
- make your life administering your machines much more enjoyable.
+title: "The Power(ful Tooling) of Gentoo"
+date: 2019-07-22
+tags:
+- Gentoo
---
-{% markdown %}
People often ask me for my reasons to use [Gentoo](https://gentoo.org/). Many
perceive it as a "hard" distro that takes a lot of time. While it does come
with a learning curve, I don't perceive it as particularly "hard", as the
documentation is very thorough and the community is very helpful. And the
tooling you get to maintain your system is far beyond what I've come across
with any other GNU+Linux distribution.
-{% endmarkdown %}
-{% markdown %}
This blog post will highlight some of the key features I love about Gentoo.
There are certainly many more perks that I don't (yet) use, so please feel free
to inform me of other cool things that I missed.
-{% endmarkdown %}
-{% markdown %}
## Configurability
One of the main reasons for preferring Gentoo is due to the ease of configuring
@@ -68,9 +60,8 @@ be applied, all you have to do is drop it in a directory in
`/etc/portage/patches`. The directory is should be in is the same as the
package's name the patch is intended for. For instance, I have the following
patch in `/etc/portage/patches/www-client/firefox`:
-{% endmarkdown %}
-{% highlight diff %}
+```diff
diff --git a/browser/extensions/moz.build b/browser/extensions/moz.build
index 6357998..c5272a2 100644
--- a/browser/extensions/moz.build
@@ -90,9 +81,8 @@ index 6357998..c5272a2 100644
- 'screenshots',
'webcompat',
]
-{% endhighlight %}
+```
-{% markdown %}
Whenever a new Firefox is released and built, this patch will be applied on it
to remove some of the features I dislike.
@@ -185,5 +175,3 @@ information. I use this mostly to see compile times of certain packages using
`qlop -Htvg <package-name>`. Using this, I can more easily deduce if I want my
desktop (with a stronger CPU) to compile a certain package, or if it'll be
faster to just compile it on my laptop.
-
-{% endmarkdown %}
diff --git a/src/_posts/2019-08-10-the-soc-controversy.html b/content/posts/2019/2019-08-10-the-soc-controversy.md
index b18cad2..f6cf47c 100644
--- a/src/_posts/2019-08-10-the-soc-controversy.html
+++ b/content/posts/2019/2019-08-10-the-soc-controversy.md
@@ -1,20 +1,19 @@
---
title: The SoC Controversy
-layout: post
-tags: Perl6 Conference CodeOfConduct Raku
-description: >
- For a while now, there's been a controversy about Standards or Codes of
- Conduct. This has also sprung up in the context of PerlCon. I'd like to
- address the issue for myself.
+date: 2019-08-10
+tags:
+- CodeOfConduct
+- Conference
+- Perl6
+- Raku
---
-{% admonition_md Disclaimer %}
+{{< admonition title="Disclaimer" >}}
Please keep in mind that the opinion shared in this blog post is mine and mine
alone. I do not speak for any other members of the PerlCon organization team.
Please do not address anyone but me for the positions held in this post.
-{% endadmonition_md %}
+{{< / admonition >}}
-{% markdown %}
Those that know me are probably aware that I generally dislike to make
political posts on my personal blog. I'd rather stick to technological
arguments, as there's less problems to be found with regards to personal
@@ -23,26 +22,20 @@ mature), I find it harder to keep politics out of my life as I interact with
online communities. This becomes especially true as I plan to assist with
organizing [PerlCon
2020](https://wiki.perlcon.eu/doku.php/proposals/2020/amsterdam).
-{% endmarkdown %}
-{% markdown %}
PerlCon 2019 ended yesterday, and I had a lot of fun. I'd like to thank the
organizer, Andrew Shitov, once more for doing an amazing job. Especially so, as
he has been harassed for weeks, for trying to organize the conference. The
reason behind the harassment was partly due to his decision to not have an SoC,
or "Standards of Conduct", for PerlCon 2019.
-{% endmarkdown %}
-{% markdown %}
During his final announcements at the end of the conference, he noted that this
is still happening, even in person at the conference itself. This toxic
behavior towards him has made him decide to no longer involve himself in
organizing a conference for the Perl community. I personally think this is a
loss for everyone involved in the community, and one that was completely
avoidable by having humane discussion instead of going for Twitter harassment.
-{% endmarkdown %}
-{% markdown %}
For what it's worth, I think Twitter is also the worst possible place on the
Internet for any reasonable discussion, as it puts a very low limit on the
amount of characters you are allowed to spend on a single post. This makes it
@@ -52,17 +45,13 @@ instance](https://soc.fglt.nl/main/public) for my social media presence on the
Internet. If anyone is on the Internet with the intent of having interesting
discussion, I'd highly recommend to use some entrance into the Fediverse. The
instance I'm using is open for sign-ups!
-{% endmarkdown %}
-{% markdown %}
But I digress. The SoC controversy is what made me want to write this blog
post. I wonder why this even is a controversy. Why do people think it is
impossible to co-exist without some document describing explicitly what is and
is not allowed? I would hope that we're all adults, and can respect one another
as such.
-{% endmarkdown %}
-{% markdown %}
I wonder, was there any certain event at PerlCon 2019 that would've been
avoided if there *was* a SoC provided? I certainly did not, at any point, feel
that people were being harmful to one another, but maybe I'm just blind to it.
@@ -71,9 +60,7 @@ that a SoC could've prevented, I would be genuinely interested in hearing about
them. If I am to assist in organizing PerlCon 2020, and I want to be able to
present a good argument on the SoC discussion, I'll need concrete examples of
real problems that have occurred.
-{% endmarkdown %}
-{% markdown %}
Of course, I also consider the opposite of this discussion. Can the SoC be used
to *cause* harm, in stead of deter it? For this, I actually have clear
evidence, and the answer is a resounding **yes**. The harassment brought upon
@@ -82,16 +69,12 @@ in Pittsburgh (2019). A video was removed, and a speaker harassed, for
dead-naming someone. Until that event, I wasn't even aware of the term, but
apparently it's grounds for removal of your presentation from the conference
archives.
-{% endmarkdown %}
-{% markdown %}
A similar event happened with The Perl Conference in Glasgow (2018), where a
talk was also removed from the archives for a supposedly offensive joke that
was made. This also sparked a heavy discussion on IRC back then, with people
from all sides pitching in with their opinion.
-{% endmarkdown %}
-{% markdown %}
From my perspective, the people shouting the loudest in these discussions
aren't interested in making the world a better place where we can live in
harmony, but to punish the offender for their behavior. I don't think we
@@ -100,22 +83,16 @@ being angry, shouting at people (either in real life, or over the Internet)
isn't going to solve any underlying problem. It is more likely to cause more
issues in the long run, where people will just be more divided, and will want
to get continuous revenge upon the other side.
-{% endmarkdown %}
-{% markdown %}
Additionally, I think that the existence of an SoC or likewise document is a
sign towards outsiders that your community can't behave itself maturely. They
need special rules laid out to them, after all. Like most rules, they are
codified because issues have arisen in the past, and keep on arising. I don't
think the Perl community is too immature to behave itself. I trust in the good
faith of people, and to me it feels like a SoC does the exact opposite.
-{% endmarkdown %}
-{% markdown %}
I hope this blog post does it's job to invite you kindly to share your opinions
-with me, either on [IRC, email or on the Fediverse]({{
-"#communication-channels" | prepend: site.baseurl | prepend: site.url }}). I'd
+with me, either on [IRC, email or on the Fediverse](/#contact). I'd
gladly start a discussion on the positive and negative effects the SoC has, and the problems
it solves and creates. I think a civil discussion is in order here, to best
prepare us for PerlCon 2020.
-{% endmarkdown %}
diff --git a/src/_posts/2019-10-17-getting-thigs-done-with-app-gtd.html b/content/posts/2019/2019-10-17-getting-things-done-with-app-gtd.md
index 2f67be0..0a24e57 100644
--- a/src/_posts/2019-10-17-getting-thigs-done-with-app-gtd.html
+++ b/content/posts/2019/2019-10-17-getting-things-done-with-app-gtd.md
@@ -1,23 +1,18 @@
---
-title: Getting Things Done with App::GTD
-layout: post
-tags: Perl6 Raku GettingThingsDone
-description: >
- My $day-job has introduced me to this concept of "Getting Things Done", and I
- have been convinced to give it a shot. However, I could not find a good free
- software program to assist me with following this lifestyle. Thus I brought
- App::GTD to the world.
+title: "Getting Things Done with App::GTD"
+date: 2019-10-07
+tags:
+- GettingThingsDone
+- Perl6
+- Raku
---
-{% markdown %}
A couple months ago, I was given a workshop at work about "getting things
done". There I was told that there exists a concept called "[Getting Things
Done](https://en.wikipedia.org/wiki/Getting_Things_Done)", or "GTD" for short,
to help you, well, get things done. A number of web-based tools were introduced
to assist us with following the rules laid out in the concept.
-{% endmarkdown %}
-{% markdown %}
## The problem
The tools that were introduced did their job, and looked reasonably shiny.
@@ -28,9 +23,7 @@ problem could've been resolved. However, my other problem with all these
programs was that they're all proprietary. Those who've read more of my blog
may have realized by now that I strongly prefer free software whenever
possible.
-{% endmarkdown %}
-{% markdown %}
Being unable to find any free software programs to fulfill my needs, I took a
look at the features I would need, and tried to adapt other programs to fit
those particular needs. I quickly learned that it's inconvenient at best to try
@@ -38,9 +31,7 @@ and mold generic task keeping programs into the specifics of GTD. But, it did
give me a reasonable idea of what features I needed for basic usage. It
occurred to me that it shouldn't be terribly hard to just write something of my
own. So I did.
-{% endmarkdown %}
-{% markdown %}
## The solution, `App::GTD`
Introducing [`App::GTD`](https://gitlab.com/tyil/raku-app-gtd), a brand new
@@ -50,73 +41,60 @@ and another colleague. In its bare basics, it's just another to-do list, but
the commands it gives you incorporate the concepts of GTD. There's an inbox
that you fill up through the day, a list of next items to work on, and projects
to structure larger tasks in.
-{% endmarkdown %}
-{% admonition_md Note %}
+{{< admonition title="note" >}}
The Raku programming language used to be called the Perl 6 programming
language. They function the same, but the name was changed for various reasons
I will not get into here.
-{% endadmonition_md %}
+{{< / admonition >}}
-{% markdown %}
This program can be installed using `zef`, though I'm planning an `ebuild` for
Gentoo (and derivatives) too. Once installed, you can use `gtd` from your
shell. Doing so without arguments will show the usage information. The most
important will be `gtd add`, `gtd next` and `gtd done`. Most of these commands
require an `id` argument. The IDs required are displayed in front of the items
when listing them with commands like `inbox` or `next`.
-{% endmarkdown %}
-{% markdown %}
## Daily life with `gtd`
Once you have `gtd` installed, you don't *need* to do any configuration, as the
defaults should work fine for most people. This means you can start using it
immediately if you want to try it out!
-{% endmarkdown %}
-{% markdown %}
The most common invocation will be with the `add` sub-command. Whenever
something pops up that needs doing, you add it to your inbox using it.
-{% endmarkdown %}
-{% highlight sh %}
+```txt
gtd add Buy eggs
gtd add "update cpan-raku's help command"
-{% endhighlight %}
+```
-{% markdown %}
These items go to your inbox, and don't need to be long, so long as *you*
understand what you meant by it. You can see that you also don't need to use
quotes around the item you want to add. All arguments after `add` will be
joined together as a string again, but some shells may perform their magic on
certain things. This is why I quoted the second call, but not the first.
-{% endmarkdown %}
-{% markdown %}
All these things that you write down like this need to be sorted out at some
point. I do this every day in the morning, before I get to my regular tasks at
work. To get started, I want to see an overview of your inbox, for which the
`inbox` sub-command is intended. Running it will give you a list of all the
items in your inbox, including their ID and the date they were added.
-{% endmarkdown %}
-{% highlight text %}
+```txt
$ gtd inbox
[1] Buy eggs (2019-10-17)
[2] update cpan-raku's help command (2019-10-17)
-{% endhighlight %}
+```
-{% markdown %}
Now I can go through the list, and decide which actions I should undertake
specifically. These are called "next items", and the sub-command is named
`next`. Called without arguments it will give you an overview of your next
items, but when given an ID it will move an inbox item to your list of next
items. You can optionally also specify a new name for the item, to be more
clear about what needs doing.
-{% endmarkdown %}
-{% highlight text %}
+```txt
$ gtd next
You're all out of Next actions!
@@ -126,30 +104,26 @@ $ gtd next 1
$ gtd next 2 "Add usage and repo info to cpan-raku, whenever it's messaged with 'help'"
"Add usage and repo info to cpan-raku, whenever it's messaged with 'help'" has
been added as a Next item.
-{% endhighlight %}
+```
-{% markdown %}
You can now see that your inbox is empty when using `inbox`, and see a list of
the next items you created with `next`.
-{% endmarkdown %}
-{% highlight text %}
+```txt
$ gtd inbox
Your inbox is empty!
$ gtd next
[1] Buy eggs (2019-10-17)
[2] Add usage and repo info to cpan-raku, whenever it's messaged with 'help' (2019-10-17)
-{% endhighlight %}
+```
-{% markdown %}
Now all that's left is to do all the things you've created next items for. When
done, you can remove the entry from your next items using `done`. This command
also works on items in your inbox, so small tasks that require no next item(s)
can be marked as done immediately.
-{% endmarkdown %}
-{% highlight text %}
+```txt
$ gtd done 1
"Buy eggs" has been removed from your list.
@@ -159,9 +133,8 @@ been removed from your list.
$ gtd next
You're all out of Next actions!
-{% endhighlight %}
+```
-{% markdown %}
## Future plans
The basics are here, but there are some things I'd very much like to add. First
@@ -191,4 +164,3 @@ I hope that `App::GTD` can help others to get things done as well. The program
is all but finished, but it should be usable for people besides me and my
colleague by now. If you have any suggestions or questions about the program,
do not hesitate to seek me out!
-{% endmarkdown %}
diff --git a/content/posts/2019/_index.md b/content/posts/2019/_index.md
new file mode 100644
index 0000000..b69640f
--- /dev/null
+++ b/content/posts/2019/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2019
+---
diff --git a/src/_posts/2020-01-08-running-cgit-on-gentoo.md b/content/posts/2020/2020-01-08-running-cgit-on-gentoo.md
index fc45e33..085da26 100644
--- a/src/_posts/2020-01-08-running-cgit-on-gentoo.md
+++ b/content/posts/2020/2020-01-08-running-cgit-on-gentoo.md
@@ -1,12 +1,10 @@
---
title: Running cgit on Gentoo
-layout: post
-tags: git cgit Gentoo
-social:
- mastodon: https://soc.fglt.nl/notice/9rG9O32VTSYnlL451U
-description: >
- Recently, I've setup cgit on my desktop, running Gentoo. This post covers the
- installation and configuration I've undertaken to get it running as desired.
+date: 2020-01-08
+tags:
+- git
+- cgit
+- Gentoo
---
[cgit](https://git.zx2c4.com/cgit/about/), a web interface for git
@@ -32,9 +30,9 @@ For this to work, there is more than just cgit to install. There are a number
of ways to set this up, but I chose for Nginx as web server, and `uwsgi` as the
handler for the fastcgi requests.
-{% highlight sh %}
+```txt
emerge dev-python/pygments www-apps/cgit www-servers/nginx www-servers/uwsgi
-{% endhighlight %}
+```
## Configuring all elements
@@ -45,7 +43,7 @@ After installation, each of these packages needs to be configured.
The configuration file for cgit resides in `/etc/cgitrc`. After removing all
the comments, the contents of my `/etc/cgitrc` can be found below.
-{% highlight text %}
+```txt
# Fixes for running cgit in a subdirectory
css=/git/cgit.css
logo=/git/cgit.png
@@ -69,7 +67,7 @@ source-filter=/usr/lib64/cgit/filters/syntax-highlighting.py
# Scan paths for repos
scan-path=/home/tyil/.local/srv/cgit
-{% endhighlight %}
+```
You should probably update the values of `root-desc`, `clone-prefix` and
`scan-path`. The first describes the small line of text at the top of the web
@@ -101,7 +99,7 @@ case, this file is at `/usr/lib64/cgit/filters/about-formatting.sh`. Open up
this file in your favorite `$EDITOR` and add another entry to the `case` for
[Pod6](https://docs.raku.org/language/pod) to call Raku.
-{% highlight sh %}
+```sh
case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
*.markdown|*.mdown|*.md|*.mkd) exec ./md2html; ;;
*.pod6) exec raku --doc=HTML::Section; ;;
@@ -110,7 +108,7 @@ case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
*.htm|*.html) exec cat; ;;
*.txt|*) exec ./txt2html; ;;
esac
-{% endhighlight %}
+```
#### Highlighting style
@@ -167,7 +165,7 @@ make a copy of it, and call it `/etc/conf.d/uwsgi.cgit`. The standard file
exists solely as a base template. For brevity, I left out all the comments in
the contents below.
-{% highlight sh %}
+```sh
UWSGI_SOCKET=
UWSGI_THREADS=0
UWSGI_PROGRAM=
@@ -183,7 +181,7 @@ UWSGI_EMPEROR_PATH=
UWSGI_EMPEROR_PIDPATH_MODE=0770
UWSGI_EMPEROR_GROUP=
UWSGI_EXTRA_OPTIONS="--ini /etc/uwsgi.d/cgit.ini"
-{% endhighlight %}
+```
That covers the service configuration file. When things don't work the way you
expect, specify a path in `UWSGI_LOG_FILE` to see its logs. Additionally, you
@@ -194,7 +192,7 @@ Now comes the application configuration, which will be read from
`/etc/uwsgi.d/cgit.ini`, according to `UWSGI_EXTRA_OPTIONS`. Create that file
with the following contents.
-{% highlight ini %}
+```ini
[uwsgi]
master = true
plugins = cgi
@@ -205,7 +203,7 @@ procname-master = uwsgi cgit
processes = 1
threads = 2
cgi = /usr/share/webapps/cgit/1.2.1/hostroot/cgi-bin/cgit.cgi
-{% endhighlight %}
+```
Note that the `cgi` value contains the version number of `www-apps/cgit`. You
may need to come back after an upgrade and update it accordingly.
@@ -217,10 +215,10 @@ variant, its just a template. This time, however, don't make a copy of it, but
a symlink. It does not need to be edited, but the name must be the same as the
`conf.d` entry name. That would be `uwsgi.cgit`.
-{% highlight sh %}
+```txt
cd /etc/conf.d
ln -s uwsgi uwsgi.cgit
-{% endhighlight %}
+```
Now you can start the service with `rc-service uwsgi.cgit start`. If a
consequent `status` notes the state as *Started*, you're all good. If the state
@@ -228,13 +226,13 @@ says *Crashed*, you should go back and double-check all configuration files.
When those are correct and you can't figure out why, feel free to reach out to
me via email.
-{% highlight sh %}
+```txt
rc-service uwsgi.cgit start
rc-service uwsgi.cgit service
# Start this after boot
rc-update add uwsgi.cgit
-{% endhighlight %}
+```
### nginx
@@ -244,7 +242,7 @@ set up nginx from scratch is beyond the scope of this post. Assuming you know
how to configure this, add the following `location` blocks to the `server`
definition for the vhost you want to make `cgit` available on.
-{% highlight nginx %}
+```nginx
location "/git" {
alias /usr/share/webapps/cgit/1.2.1/htdocs;
try_files $uri @cgit;
@@ -261,7 +259,7 @@ location @cgit {
fastcgi_split_path_info ^(/git/?)(.+)$;
uwsgi_param PATH_INFO $fastcgi_path_info;
}
-{% endhighlight %}
+```
Once saved, you can reload `nginx`, and the `$HOSTNAME/git` endpoint can be
reached, and should display an cgit page, detailing there are no repositories.
@@ -291,7 +289,7 @@ so I that can also be skipped as a manual task. This script may be of use to
you if you want to more quickly start a new project.
You can find this script [in my dotfiles
-repository](https://home.tyil.nl/git/dotfiles/tree/.local/bin/git-mkbare).
+repository](https://git.tyil.nl/dotfiles/tree/.local/bin/git-mkbare).
## Wrapping up
diff --git a/src/_posts/2020-05-30-setting-up-pgp-wkd.md b/content/posts/2020/2020-05-30-setting-up-pgp-wkd.md
index 147f8c0..26b6e44 100644
--- a/src/_posts/2020-05-30-setting-up-pgp-wkd.md
+++ b/content/posts/2020/2020-05-30-setting-up-pgp-wkd.md
@@ -1,14 +1,13 @@
---
+date: 2020-05-30
title: Setting Up a PGP Webkey Directory
-layout: post
-tags: PGP GPG WKD Security
-social:
- email: mailto:~tyil/public-inbox@lists.sr.ht&subject=Setting Up a PGP Webkey Directory
- mastodon: https://soc.fglt.nl/notice/9vaBwcOO6ynNYfT7Lc
-description: >
- A friend on IRC asked me how I made my PGP key available in a webkey
- directory. This post will detail my path, so you can easily set it up for
- yourself.
+tags:
+- PGP
+- GPG
+- WKD
+- Security
+aliases:
+- /post/2020/05/30/setting-up-pgp-wkd/
---
A little while ago, a friend on IRC asked me how I set up a PGP webkey
@@ -16,9 +15,9 @@ directory on my website. For those that don't know, a webkey directory is a
method to find keys through `gpg`'s `--locate-key` command. This allows people
to find my key using this command:
-{% highlight sh %}
+```txt
gpg --locate-key p.spek@tyil.nl
-{% endhighlight %}
+```
This is a very user-friendly way for people to get your key, as compared to
using long IDs.
@@ -32,22 +31,22 @@ For a webkey directory to work, you simply need to have your key available at a
certain path on your website. The base path for this is
`.well-known/openpgpkey/`.
-{% highlight sh %}
+```sh
mkdir -p .well-known/openpgpkey
-{% endhighlight %}
+```
The webkey protocol will check for a `policy` file to exist, so you must create
this too. The file can be completely empty, and that's exactly how I have it.
-{% highlight sh %}
+```sh
touch .well-known/openpgpkey/policy
-{% endhighlight %}
+```
The key(s) will be placed in the `hu` directory, so create this one too.
-{% highlight sh %}
+```sh
mkdir .well-known/openpgpkey/hu
-{% endhighlight %}
+```
## Adding your PGP key
@@ -55,13 +54,13 @@ The key itself is just a standard export of your key, without ASCII armouring.
However, the key does need to have its file **name** in a specific format.
Luckily, you can just show this format with `gpg`'s `--with-wkd-hash` option.
-{% highlight sh %}
+```sh
gpg --with-wkd-hash -k p.spek@tyil.nl
-{% endhighlight %}
+```
This will yield output that may look something like this:
-{% highlight text %}
+```txt
pub rsa4096/0x7A6AC285E2D98827 2018-09-04 [SC]
Key fingerprint = 1660 F6A2 DFA7 5347 322A 4DC0 7A6A C285 E2D9 8827
uid [ultimate] Patrick Spek <p.spek@tyil.nl>
@@ -69,16 +68,16 @@ uid [ultimate] Patrick Spek <p.spek@tyil.nl>
sub rsa2048/0x031D65902E840821 2018-09-04 [S]
sub rsa2048/0x556812D46DABE60E 2018-09-04 [E]
sub rsa2048/0x66CFE18D6D588BBF 2018-09-04 [A]
-{% endhighlight %}
+```
What we're interested in is the `uid` line with the hash in the local-part of
the email address, which would be `i4fxxwcfae1o4d7wnb5bop89yfx399yf@tyil.nl`.
For the filename, we only care about the local-part itself, meaning the export
of the key must be saved in a file called `i4fxxwcfae1o4d7wnb5bop89yfx399yf`.
-{% highlight sh %}
+```sh
gpg --export 0x7A6AC285E2D98827 > .well-known/openpgpkey/hu/i4fxxwcfae1o4d7wnb5bop89yfx399yf
-{% endhighlight %}
+```
## Configuring your webserver
@@ -86,13 +85,13 @@ Lastly, your webserver may require some configuration to serve the files
correctly. For my blog, I'm using [`lighttpd`](https://www.lighttpd.net/), for
which the configuration block I'm using is as follows.
-{% highlight lighttpd %}
+```lighttpd
$HTTP["url"] =~ "^/.well-known/openpgpkey" {
setenv.add-response-header = (
"Access-Control-Allow-Origin" => "*",
)
}
-{% endhighlight %}
+```
It may be worthwhile to note that if you do any redirection on your domain,
such as adding `www.` in front of it, the key lookup may fail. The error
diff --git a/src/_posts/2020-06-21-lately-in-raku.md b/content/posts/2020/2020-06-21-lately-in-raku.md
index fed891a..3d54bdc 100644
--- a/src/_posts/2020-06-21-lately-in-raku.md
+++ b/content/posts/2020/2020-06-21-lately-in-raku.md
@@ -1,12 +1,8 @@
---
title: Lately in Raku
-layout: post
-tags: Raku
-social:
- email: mailto:~tyil/public-inbox@lists.sr.ht&subject=Lately in Raku
- mastodon: https://soc.fglt.nl/notice/9wIq8QpmdRpsP4Qrr6
-description: >
- A post on some Raku stuff I've been working on lately.
+date: 2020-06-21
+tags:
+- Raku
---
I've been working on some Raku projects, but each of them is *just* too small
@@ -40,12 +36,14 @@ The first plugin I've created can do dice rolls, D&D style. You can roll any
number of dice, with any number of sides, and add (or subtract) bonusses from
these.
- <@tyil> .roll 1d20
- <+musashi> 1d20 = 1
- <@tyil> .roll 5d20
- <+musashi> 5d20 = 3 + 19 + 8 + 6 + 11 = 47
- <@tyil> .roll 1d8+2d6+10
- <+musashi> 1d8+2d6+10 = 4 + 6 + 4 + 10 = 24
+```txt
+<@tyil> .roll 1d20
+<+musashi> 1d20 = 1
+<@tyil> .roll 5d20
+<+musashi> 5d20 = 3 + 19 + 8 + 6 + 11 = 47
+<@tyil> .roll 1d8+2d6+10
+<+musashi> 1d8+2d6+10 = 4 + 6 + 4 + 10 = 24
+```
Since this is ripe for abuse, the plugin allows to set limits, and sets some
defaults for the limits as well. This should help prevent your bot from getting
@@ -57,9 +55,11 @@ Everyone forgets things, and there's various tools helping people remember
things in various situations. For IRC based situations, I created a reminder
plugin for `IRC::Client`.
- 10:19 <@tyil> musashi: remind me to write a blog post in 10 minutes
- 10:19 <+musashi> Reminding you to write a blog post on 2020-06-21T08:29:00Z (UTC)
- 10:29 <+musashi> tyil: Reminder to write a blog post
+```txt
+10:19 <@tyil> musashi: remind me to write a blog post in 10 minutes
+10:19 <+musashi> Reminding you to write a blog post on 2020-06-21T08:29:00Z (UTC)
+10:29 <+musashi> tyil: Reminder to write a blog post
+```
It's not very sophisticated yet, working only with numbers and certain
identifiers (minutes, hours, days, weeks), but I may add more useful
@@ -84,8 +84,7 @@ all the required things nicely fit into a single file.
I had not used `$=pod` before in Raku, and I'm quite happy with how easy it is
to use, though I would like a cleaner way to refer to a Pod block by name.
-{% highlight perl6 %}
-{% raw %}
+```raku
#!/usr/bin/env raku
use v6.d;
@@ -153,5 +152,4 @@ Written and signed on the {{ date }}.
For the association, Lan Torrez
For the {{ contractor }}
=end template
-{% endraw %}
-{% endhighlight %}
+```
diff --git a/src/_posts/2020-07-15-config-3.0.md b/content/posts/2020/2020-07-15-config-3.0.md
index 9fb33c0..2b77dae 100644
--- a/src/_posts/2020-07-15-config-3.0.md
+++ b/content/posts/2020/2020-07-15-config-3.0.md
@@ -1,14 +1,9 @@
---
title: Config 3.0
-layout: post
-tags: Raku Programming
-social:
- email: mailto:~tyil/public-inbox@lists.sr.ht&subject=Config 3.0
- mastodon: https://soc.fglt.nl/notice/9x8QT2TxD2dSlEYse8
-description: >
- I've made a reasonably sized change to Raku's Config module, resulting in a
- major version bump. This article details my reasoning behind it, and shows
- some examples on how I think I solved the issues at hand.
+date: 2020-07-15
+tags:
+- Raku
+- Programming
---
For those who don't know, the
@@ -37,7 +32,7 @@ I set out to make an automated way to read those too.
First, let's take a look at how it used to work. Generally, I'd create the
default configuration structure and values first.
-{% highlight perl6 %}
+```raku
use Config;
my $config = Config.new.read({
@@ -47,14 +42,14 @@ my $config = Config.new.read({
},
version => 3,
});
-{% endhighlight %}
+```
And after that, check for potential configuration file locations, and read any
that exist.
-{% highlight perl6 %}
+```raku
$config.read($*HOME.add('config/project.toml').absolute);
-{% endhighlight %}
+```
The `.absolute` call was necessary because I wrote the initial `Config` version
with the `.read` method not supporting `IO::Path` objects. A fix for this has
@@ -72,7 +67,7 @@ So, how does the new version improve this? For starters, the `.new` method of
structure, and optionally types *or* default values of your configuration
object.
-{% highlight perl6 %}
+```raku
use Config;
my $config = Config.new({
@@ -82,13 +77,13 @@ my $config = Config.new({
},
version => 3,
}, :name<project>);
-{% endhighlight %}
+```
-{% admonition_md note %}
+{{< admonition title="note" >}}
`foo` has been made into the `Str` *type object*, rather than a `Str` *value*.
This was technically allowed in previous `Config` versions, but it comes with
actual significance in 3.0.
-{% endadmonition_md %}
+{{< / admonition >}}
Using `.new` instead of `.read` is a minor syntactic change, which saves 1 word
per program. This isn't quite that big of a deal. However, the optional `name`
@@ -126,11 +121,11 @@ is prefixed with the `name`. Lastly, all the variable names are uppercased.
For the example `Config` given above, this would result in the following
environment variables being checked.
-{% highlight sh %}
+```sh
$PROJECT_FOO
$PROJECT_ALPHA_BETA
$PROJECT_VERSION
-{% endhighlight %}
+```
If any are found, they're also cast to the appropriate type. Thus,
`$PROJECT_FOO` would be cast to a `Str`, and so would `$PROJECT_ALPHA_BETA`. In
@@ -155,11 +150,11 @@ environment variable, as per the `Log` module's interface. When set to `7` (for
"debug"), it will print the configuration files that are being merged into your
`Config` and which environment veriables are being used as well.
-{% admonition_md note %}
+{{< admonition title="note" >}}
A downside is that the application using `Config` for its configuration must
also support `Log` to actually make the new logging work. Luckily, this is
quite easy to set up, and there's example code for this in `Log`'s README.
-{% endadmonition_md %}
+{{< / admonition >}}
## Too Fancy For Me
diff --git a/src/_posts/2020-07-19-freebsd-mailserver-part-6-system-updates.md b/content/posts/2020/2020-07-19-freebsd-mailserver-part-6-system-updates.md
index 5094eba..f3d1e89 100644
--- a/src/_posts/2020-07-19-freebsd-mailserver-part-6-system-updates.md
+++ b/content/posts/2020/2020-07-19-freebsd-mailserver-part-6-system-updates.md
@@ -1,13 +1,12 @@
---
title: "FreeBSD Email Server - Part 6: System Updates"
-layout: post
-tags: Tutorial FreeBSD Email
+date: 2020-07-19
+tags:
+- Email
+- FreeBSD
+- Tutorial
social:
email: mailto:~tyil/public-inbox@lists.sr.ht&subject=FreeBSD Email Server
- mastodon: https://soc.fglt.nl/notice/9xF5VVpcK1NJR0kgOO
-description: >
- Updates are important. This article aims to help you to learn from my
- mistakes, so your updates will go smooth.
---
Four years have past, and my FreeBSD email server has keps on running without
@@ -17,9 +16,9 @@ it didn't do 1.3 yet, just 1.2. I set out to do a relatively simple system
update, which didn't go as smooth as I had hoped. This tutorial post should
help you avoid the mistakes I made, so your updates *will* go smooth.
-{% admonition_md info %}
+{{< admonition title="info" >}}
The rest of this tutorial assumes you're running as the `root` user.
-{% endadmonition_md %}
+{{< / admonition >}}
## Preparations
@@ -34,12 +33,12 @@ their configurations are in `zroot/usr/local`. My database's data is stored on
`zroot/postgres/data96`. Additionally, I want to make a snapshot of
`zroot/usr/ports`.
-{% highlight sh %}
+```txt
zfs snapshot -r zroot/srv@`date +%Y%m%d%H%M%S`-11.0-final
zfs snapshot -r zroot/usr/local@`date +%Y%m%d%H%M%S`-11.0-final
zfs snapshot -r zroot/postgres@`date +%Y%m%d%H%M%S`-11.0-final
zfs snapshot -r zroot/usr/ports@`date +%Y%m%d%H%M%S`-11.0-final
-{% endhighlight %}
+```
This will make a snapshot of each of these locations, for easy restoration in
case any problems arise. You can list all your snapshots with `zfs list -t
@@ -56,9 +55,9 @@ The services and their configuration can be recreated, just follow the earlier
parts of this series again. The email data, however, cannot. This is the data
in `/srv/mail`. You can make a local copy of all this data using `rsync`.
-{% highlight sh %}
+```txt
rsync -av example.org:/srv/mail/ ~/mail-backup
-{% endhighlight %}
+```
There's one more thing to do, which I learned the hard way. Set your login
shell to a simple one, provided by the base system. The obvious choice is
@@ -66,14 +65,14 @@ shell to a simple one, provided by the base system. The obvious choice is
major version update, the ABI changes, which will temporarily break most of
the user-installed packages, including your shell.
-{% highlight sh %}
+```txt
chsh
-{% endhighlight %}
+```
-{% admonition_md warning %}
+{{< admonition title="warning" >}}
Be sure to change the shell for whatever user you're using to SSH into this
machine too, if any!
-{% endadmonition_md %}
+{{< / admonition >}}
## Updating the Base System
@@ -82,40 +81,40 @@ actual updates can begin. FreeBSD has a dedicated program to handle updating
the base system, `freebsd-update`. First off, fetch any updates, and make sure
all the updates for your current version are applied.
-{% highlight sh %}
+```txt
freebsd-update fetch install
-{% endhighlight %}
+```
Afterwards, set the new system version you want to update to. In my case, this
is `12.1-RELEASE`, but if you're reading this in the future, you most certainly
want a newer version.
-{% highlight sh %}
+```txt
freebsd-update -r 12.1-RELEASE upgrade
-{% endhighlight %}
+```
This command will ask you to review the changes and confirm them as well. It
should generally be fine, but this is your last chance to make any backups or
perform other actions to secure your data! If you're ready to continue, install
the updates to the machine.
-{% highlight sh %}
+```txt
freebsd-update install
-{% endhighlight %}
+```
At this point, your kernel has been updated. Next you must reboot to start
using the new kernel.
-{% highlight sh %}
+```txt
reboot
-{% endhighlight %}
+```
Once the system is back online, you can continue installing the rest of the
updates.
-{% highlight sh %}
+```txt
freebsd-update install
-{% endhighlight %}
+```
When this command finishes, the base system has been updated and should be
ready for use. Next up is updating all the software you installed manually.
@@ -135,18 +134,18 @@ installed through `pkg`. Currently, `pkg` itself doesn't even work. Luckily,
FreeBSD has `pkg-static`, which is a statically compiled version of `pkg`
intended to fix this very problem. Let's fix up `pkg` itself first.
-{% highlight sh %}
+```txt
pkg-static install -f pkg
-{% endhighlight %}
+```
That will make `pkg` itself work again. Now you can use `pkg` to update package
information, and upgrade all packages to a version that works under this
FreeBSD version.
-{% highlight sh %}
+```txt
pkg update
pkg upgrade
-{% endhighlight %}
+```
#### PostgreSQL
@@ -159,18 +158,18 @@ PostgreSQL again, restart the database, run a `pgdump`, upgrade, restart and
import. However, I find it much cleaner to use FreeBSD jails to solve this
issue.
-{% admonition_md info %}
+{{< admonition title="info" >}}
My original installation used PostgreSQL 9.6, you may need to update some
version numbers accordingly!
-{% endadmonition_md %}
+{{< / admonition >}}
I generally put my jails in a ZFS subvolume, so let's create one of those
first.
-{% highlight sh %}
+```txt
zfs create -o mountpoint=/usr/jails zroot/jails
zfs create zroot/jails/postgres96
-{% endhighlight %}
+```
This will create a new subvolume at `/usr/jails/postgres96`. Using
`bsdinstall`, a clean FreeBSD installation usable by the jail can be set up
@@ -178,15 +177,15 @@ here. This command will give you some popups you may remember from installing
FreeBSD initially. This time, you can uncheck *all* boxes, to get the most
minimal system.
-{% highlight sh %}
+```txt
bsdinstall jail /usr/jails/postgres96
-{% endhighlight %}
+```
When `bsdinstall` finishes, you can configure the jail. This is done in
`/etc/jail.conf`. If this file doesn't exist, you can create it. Make sure the
following configuration block is written to the file.
-{% highlight cfg %}
+```cfg
postgres96 {
# Init information
exec.start = "/bin/sh /etc/rc";
@@ -208,70 +207,70 @@ postgres96 {
allow.raw_sockets;
allow.sysvipc;
}
-{% endhighlight %}
+```
Now you can start up the jail, so it can be used.
-{% highlight sh %}
+```txt
service jail onestart postgres96
-{% endhighlight %}
+```
Using the host system's `pkg`, you can install PostgreSQL into the jail.
-{% highlight sh %}
+```txt
pkg -c /usr/jails/postgres96 install postgresql96-server
-{% endhighlight %}
+```
Now you just need to make the data directory available to the jail, which you
can most easily do using
[`nullfs`](https://www.freebsd.org/cgi/man.cgi?query=nullfs&sektion=&n=1).
-{% highlight sh %}
+```txt
mount -t nullfs /var/db/postgres/data96 /usr/jails/postgres96/var/db/postgres/data96
-{% endhighlight %}
+```
Now everything should be ready for use inside the jail. Let's head on in using
`jexec`.
-{% highlight sh %}
+```txt
jexec postgres96
-{% endhighlight %}
+```
Once inside the jail, you can start the PostgreSQL service, and dump the `mail`
database.
-{% highlight sh %}
+```txt
service postgresql onestart
su - postgres
pg_dump mail > ~/mail.sql
-{% endhighlight %}
+```
This will write the dump to `/usr/jails/postgres96/var/db/postgres/mail.sql` on
the host system. You can leave the jail and close it down again.
-{% highlight sh %}
+```txt
exit
exit
service jail onestop postgres96
-{% endhighlight %}
+```
This dump can be imported in your updated PostgreSQL on the host system.
Connect to the database first.
-{% highlight sh %}
+```txt
su - postgres
psql
-{% endhighlight %}
+```
Then, recreate the user, database and import the data from the dump.
-{% highlight sql %}
+```sql
CREATE USER postfix WITH PASSWORD 'incredibly-secret!';
CREATE DATABASE mail WITH OWNER postfix;
\c mail
\i /usr/jails/postgres96/var/db/postgres/mail.sql
\q
-{% endhighlight %}
+```
The `mail` database is now back, and ready for use!
@@ -284,22 +283,22 @@ need manual installation, but afterwards, we can rely on `portupgrade` to do
the rest. Before doing anything with the ports collection, it should be
updated, which is done using `portsnap`.
-{% highlight sh %}
+```txt
portsnap fetch extract
-{% endhighlight %}
+```
Once this is done, you can go to the `portupgrade` directory and install it.
-{% highlight sh %}
+```txt
cd /usr/ports/ports-mgmt/portupgrade
make install clean
-{% endhighlight %}
+```
Now, to upgrade all other ports.
-{% highlight sh %}
+```txt
portupgrade -a
-{% endhighlight %}
+```
Be sure to double-check the compilation options that you are prompted about! If
you're missing a certain option, you may miss an important feature that is
@@ -312,31 +311,31 @@ out later!
Now that all user-installed software has been updated too, it's time to
finalize the update by running `freebsd-update` for a final time.
-{% highlight sh %}
+```txt
freebsd-update install
-{% endhighlight %}
+```
You can return to your favourite shell again.
-{% highlight sh %}
+```txt
chsh
-{% endhighlight %}
+```
And you can clean up the ports directories to get some wasted space back.
-{% highlight sh %}
+```txt
portsclean -C
-{% endhighlight %}
+```
I would suggest making a new snapshot as well, now that you're on a relatively
clean and stable state.
-{% highlight sh %}
+```txt
zfs snapshot -r zroot/srv@`date +%Y%m%d%H%M%S`-12.1-clean
zfs snapshot -r zroot/usr/local@`date +%Y%m%d%H%M%S`-12.1-clean
zfs snapshot -r zroot/postgres@`date +%Y%m%d%H%M%S`-12.1-clean
zfs snapshot -r zroot/usr/ports@`date +%Y%m%d%H%M%S`-12.1-clean
-{% endhighlight %}
+```
And that concludes your system update. Your mailserver is ready to be neglected
for years again!
diff --git a/src/_posts/2020-12-14-raku-modules-in-gentoo-portage.md b/content/posts/2020/2020-12-14-raku-modules-in-gentoo-portage.md
index 2d268d1..7bb2e55 100644
--- a/src/_posts/2020-12-14-raku-modules-in-gentoo-portage.md
+++ b/content/posts/2020/2020-12-14-raku-modules-in-gentoo-portage.md
@@ -1,11 +1,11 @@
---
-layout: post
-tags: Raku Gentoo
+title: Raku Modules in Gentoo Portage
+date: 2020-12-14
+tags:
+- Raku
+- Gentoo
social:
email: mailto:~tyil/public-inbox@lists.sr.ht&subject=Raku modules in Gentoo's Portage
-description: >
- Updates are important. This article aims to help you to learn from my
- mistakes, so your updates will go smooth.
---
The last couple of days I've been taking another look at getting modules for
@@ -20,13 +20,13 @@ this method. For one, it allows installation of the same module with different
versions, or from different authors. It also handles all the Unicode complexity
for you.
-{% admonition_md note %}
+{{< admonition title="note" >}}
There *is* a
[CompUnit::Repository::FileSystem](https://docs.raku.org/type/CompUnit::Repository::FileSystem)
which would allow me to just copy over files to the right directory, however, I
quite like the ability to have multiple versions of the same module installed.
This is actually something Portage is designed with, too!
-{% endadmonition_md %}
+{{< / admonition >}}
After an email to the Raku users mailing list, I got some pointers over IRC. I
let these sink in for a couple days, considering how to approach the problem
@@ -45,7 +45,7 @@ the module to install. It does not depend on any one module manager, so it can
be used to bootstrap a user-friendly module manager (such as
[`zef`](https://github.com/ugexe/zef/)) for the user.
-{% highlight raku %}
+```raku
#| Install a Raku module.
sub MAIN (
#| The path to the Raku module sources.
@@ -73,7 +73,7 @@ sub MAIN (
$repository.install($dist, :$force);
}
-{% endhighlight %}
+```
It's a fairly straightforward program. It checks for `$D` to be set in the
environment, which is a variable Portage sets as the destination directory to
@@ -92,11 +92,11 @@ files that already exist in the system wide `site` repo. Portage will complain
about possible file collisions and refuse to install the package if these
remain. However, this can be solved rather easily by calling `rm` on these files.
-{% highlight sh %}
+```txt
rm -- "${D}/usr/share/perl6/site/version"
rm -- "${D}/usr/share/perl6/site/repo.lock"
rm -- "${D}/usr/share/perl6/site/precomp/.lock"
-{% endhighlight %}
+```
And with this, my test module, `IO::Path::XDG`, installs cleanly through the
power of Portage, and is usable by all users using the system-wide Raku
diff --git a/src/_posts/2020-12-15-merging-json-in-postgresql.md b/content/posts/2020/2020-12-15-merging-json-in-postgresql.md
index 0d7e087..8d97e50 100644
--- a/src/_posts/2020-12-15-merging-json-in-postgresql.md
+++ b/content/posts/2020/2020-12-15-merging-json-in-postgresql.md
@@ -1,12 +1,12 @@
---
-layout: post
-tags: PostgreSQL Programming JSON
+title: Merging JSON in PostgreSQL
+date: 2020-12-15
+tags:
+- JSON
+- PostgreSQL
+- Programming
social:
email: mailto:~tyil/public-inbox@lists.sr.ht&subject=Merging JSON objects in PostgreSQL
-description: >
- Left unsatisfied trying to find a nice way to merge two JSON objects in
- PostgreSQL, I whipped up my own. This small post shows off my glorious
- concoction for future generations."
---
At my `$day-job` we have a lot of `jsonb` in our database. From time to time, I
@@ -21,13 +21,13 @@ but mostly it is fun to figure it out. And who doesn’t like spending time with
The way I wanted to have it work is like this:
-{% highlight sql %}
+```sql
UPDATE user SET properties = jsonb_merge(properties, '{"notifications": {"new_case": false, "new_document": true}}');
-{% endhighlight %}
+```
And this is the eventual function I produced to do it:
-{% highlight sql %}
+```sql
CREATE OR REPLACE FUNCTION jsonb_merge(original jsonb, delta jsonb) RETURNS jsonb AS $$
DECLARE result jsonb;
BEGIN
@@ -47,4 +47,4 @@ CREATE OR REPLACE FUNCTION jsonb_merge(original jsonb, delta jsonb) RETURNS json
RETURN result;
END
$$ LANGUAGE plpgsql;
-{% endhighlight %}
+```
diff --git a/content/posts/2020/_index.md b/content/posts/2020/_index.md
new file mode 100644
index 0000000..8dad6eb
--- /dev/null
+++ b/content/posts/2020/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2020
+---
diff --git a/src/_posts/2021-05-13-a-new-irc-client.md b/content/posts/2021/2021-05-13-a-new-irc-client.md
index e52cc37..7003cb5 100644
--- a/src/_posts/2021-05-13-a-new-irc-client.md
+++ b/content/posts/2021/2021-05-13-a-new-irc-client.md
@@ -1,13 +1,12 @@
---
-layout: post
-tags: Raku IRC Programming
+date: 2021-05-13
title: A New IRC::Client
+tags:
+- Raku
+- IRC
+- Programming
social:
email: mailto:~tyil/public-inbox@lists.sr.ht&subject=A New IRC::Client
-description: >
- Due to the current iteration of IRC::Client in the Raku programming
- language's ecosystem being unmaintained, I've decided to make my own
- implementation with the intent of replacing it.
---
The Raku programming language has a popular module for creating IRC bots,
diff --git a/src/_posts/2021-05-22-raku-on-libera-chat.md b/content/posts/2021/2021-05-22-raku-on-libera-chat.md
index 9d681ed..87ce7ff 100644
--- a/src/_posts/2021-05-22-raku-on-libera-chat.md
+++ b/content/posts/2021/2021-05-22-raku-on-libera-chat.md
@@ -1,13 +1,12 @@
---
-layout: post
-tags: Raku LiberaChat IRC
+date: 2021-05-22
title: Raku is moving to Libera.chat
+tags:
+- Raku
+- LiberaChat
+- IRC
social:
email: mailto:~tyil/public-inbox@lists.sr.ht&subject=Raku is moving to Libera.chat
-description: >
- After a turbulent time among Freenode's staff, a new IRC network has spawned:
- libera.chat. Most of the original Freenode staff has moved to it, and the
- Raku Steering Council feels it is a good move for us to follow.
---
Earlier this week, the staff at the Freenode IRC network have resigned en
diff --git a/src/_posts/2021-06-04-managing-docker-compose-projects-with-openrc.md b/content/posts/2021/2021-06-04-managing-docker-compose-projects-with-openrc.md
index 76fe272..c182654 100644
--- a/src/_posts/2021-06-04-managing-docker-compose-projects-with-openrc.md
+++ b/content/posts/2021/2021-06-04-managing-docker-compose-projects-with-openrc.md
@@ -1,12 +1,11 @@
---
-layout: post
-tags: Gentoo Openrc Docker DockerCompose
+date: 2021-06-04
title: Managing Docker Compose with OpenRC
-social:
- email: mailto:~tyil/public-inbox@lists.sr.ht&subject=managing docker compose with openrc
-description: >
- A quick overview of the method I've used to manage docker-compose based
- projects/services with OpenRC.
+tags:
+- Gentoo
+- OpenRC
+- Docker
+- DockerCompose
---
On one of my machines, I host a couple services using `docker-compose`. I
@@ -24,7 +23,7 @@ The meta-service lives at `/etc/init.d/docker-compose`, just like all other
services managed by `openrc`. This file is quite straightforward. To start off,
a number of variables are set and exported.
-{% highlight sh %}
+```sh
name="$RC_SVCNAME"
description="OpenRC script for managing the $name docker-compose project"
@@ -50,13 +49,13 @@ export COMPOSE_IGNORE_ORPHANS
export COMPOSE_PARALLEL_LIMIT
export COMPOSE_INTERACTIVE_NO_CLI
export COMPOSE_DOCKER_CLI_BUILD
-{% endhighlight %}
+```
One of the services I use is also configured with its own `external` network. I
want it to be created if it doesn't exist, to ensure that the service can start
up properly. I do *not* want it to be removed, so I left that out.
-{% highlight sh %}
+```sh
# Set up (external) networks
for name in "${DOCKER_NETWORKS[@]}"
do
@@ -75,12 +74,12 @@ do
unset network_id
done
-{% endhighlight %}
+```
And lastly, there's the four simple functions to declare dependencies,
configure how to `start` or `stop`, and how to get the `status` of the service.
-{% highlight sh %}
+```sh
depend() {
need docker
}
@@ -96,29 +95,29 @@ status() {
stop() {
$DOCKER_COMPOSE --project-directory "$COMPOSE_PROJECT_DIRECTORY" down
}
-{% endhighlight %}
+```
Now, to actually create a service file to manage a `docker-compose` project, a
symlink must be made. I'll take my
[`botamusique`](https://github.com/azlux/botamusique) service as an example.
-{% highlight text %}
+```
ln -s /etc/init.d/docker-compose /etc/init.d/botamusique
-{% endhighlight %}
+```
This service can't start just yet, as there's no `$COMPOSE_PROJECT_DIRECTORY`
configured for it yet. For this, a similarly named file should be made in
`/etc/conf.d`. In here, any variable used by the service can be configured.
-{% highlight text %}
+```
$EDITOR /etc/conf.d/botamusique
-{% endhighlight %}
+```
In my case, it only pertains the `$COMPOSE_PROJECT_DIRECTORY` variable.
-{% highlight sh %}
+```
COMPOSE_PROJECT_DIRECTORY="/var/docker-compose/botamusique"
-{% endhighlight %}
+```
And that's it. For additional `docker-compose` projects I need to make only a
symlink and a configuration file. If I discover a bug or nuisance, only a
@@ -127,7 +126,7 @@ services.
For reference, here's the full `/etc/init.d/docker-compose` file.
-{% highlight sh %}
+```sh
#!/sbin/openrc-run
# Copyright 2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
@@ -192,4 +191,4 @@ status() {
stop() {
$DOCKER_COMPOSE --project-directory "$COMPOSE_PROJECT_DIRECTORY" down
}
-{% endhighlight %}
+```
diff --git a/content/posts/2021/_index.md b/content/posts/2021/_index.md
new file mode 100644
index 0000000..1287d56
--- /dev/null
+++ b/content/posts/2021/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2021
+---
diff --git a/content/posts/2022/2022-02-14-librewolf.md b/content/posts/2022/2022-02-14-librewolf.md
new file mode 100644
index 0000000..0152244
--- /dev/null
+++ b/content/posts/2022/2022-02-14-librewolf.md
@@ -0,0 +1,92 @@
+---
+date: 2022-02-14
+title: Trying out LibreWolf
+tags:
+- Firefox
+- LibreWolf
+---
+
+Over the past week, I've been trying out [LibreWolf](https://librewolf.net/) as
+an alternative to mainline Firefox. I generally don't hold a high opinion on any
+"modern" browser to begin with, but Firefox has been the least bad for quite
+some time. I used to actually like Firefox, but Mozilla has done their best to
+alienate their user base in search for profits, and is eventually left with
+neither. Their latest effort in digging their own grave is teaming up with Meta.
+
+As such, I have been searching for an alternative (modern) browser for a long
+time. One major requirement that I've had is to have something like
+[uMatrix](https://addons.mozilla.org/en-US/firefox/addon/umatrix/). And
+obviously major features to block any and all advertisements, as these are a
+major detriment to your own mental health, and to the resources your machine
+uses. So, when someone recommended me LibreWolf, which is just a more
+user-respecting fork of Firefox, I didn't hesitate to try it out.
+
+The migration from Firefox to LibreWolf was remarkably simple. Since I use [a
+small
+wrapper](https://git.tyil.nl/dotfiles/tree/.local/bin/firefox?id=1c8e9b136d9d00decc1d3570fe58072427107148)
+to launch Firefox with a specific profile directory, I just had to update that
+to launch LibreWolf instead. It kept all my settings, installed add-ons, and even
+open tabs. It seems that by default, however, it will use its own directory for
+configuration. If you want to try out LibreWolf and have a similar experience,
+you can just copy over your old Firefox configuration directory to a new
+location for use with LibreWolf. In hindsight, that probably would've been the
+safer route for me as well, but it already happened and it all went smooth, so
+no losses.
+
+Now, while LibreWolf is more-or-less like Firefox, but less harmful to its own
+users, some of the tweaks made by the LibreWolf team may or may not be desired.
+I've taken note of any differences that could be conceived as issues. So far,
+they're not breaking for me, but these may be of interest to you if you're
+looking to try LibreWolf out as well.
+
+## HTTP
+
+By default, LibreWolf will not let you visit sites over HTTP. This is generally
+a very nice feature, but for some public hot-spots, this may cause issues. These
+are generally completely unencrypted, and LibreWolf will refuse to connect. The
+page presented instead will inform you that the page you're trying to visit is
+unencrypted, and allow you to make a temporary exception. Not a very big issue,
+but it may be a little bit more annoying than you're used to.
+
+## Add-ons
+
+While all my add-ons were retained, I did want to get another add-on to redirect
+me away from YouTube, to use an Invidious instance. The page for installing
+add-ons itself seems to work fine, but upon clicking the Install button, and
+accepting the installation, LibreWolf throws an error that it simply failed to
+install anything. The Install button is nothing more than a fancy anchor with a
+link to the `xpi` file, so you can manually download the file and install the
+add-on manually through the [Add-ons Manager](about:addons).
+
+## Element
+
+I've been using Matrix for a while, as an atechnical-friendly, open source
+platform, for those unwilling to use IRC. Their recommended client,
+[Element](https://app.element.io/), is just another web page, because that's
+sadly how most software is made these days. The chat itself works without a
+hitch, but there are two minor inconveniences compared to my regular Firefox
+setup.
+
+The first one is that LibreWolf does not share my local timezone with the
+websites I visit. This causes timestamps to be off by one hour in the Element
+client. A very minor issue that I can easily live with.
+
+The other is that the "default" icons, which is a capital letter with a colored
+background, [don't look so well](https://dist.tyil.nl/blog/matrix-icons.png).
+There's some odd artifacts in the icons, which doesn't seem to affect the letter
+shown. Since I mostly use the
+[weechat-matrix](https://github.com/poljar/weechat-matrix) plugin, it's not
+really an issue. And for the few times I do use Element, it doesn't bother me
+enough to consider it a real issue.
+
+## Jellyfin
+
+For consuming all sorts of media, I have [Jellyfin](https://jellyfin.org/) set
+up for personal use. This worked fine in my regular Firefox setup, but does not
+seem to be willing to play any videos in LibreWolf. The console logs show some
+issues with websockets, and I've not been able to find a good way to work around
+this yet. For now, I'll stick to using `mpv` to watch any content to deal with
+this issue.
+
+All in all, I think LibreWolf is a pretty solid browser, and unless I discover
+something major to turn me off, I'll keep using it for the foreseeable future.
diff --git a/content/posts/2022/2022-02-20-nginx-tls.md b/content/posts/2022/2022-02-20-nginx-tls.md
new file mode 100644
index 0000000..0baef43
--- /dev/null
+++ b/content/posts/2022/2022-02-20-nginx-tls.md
@@ -0,0 +1,92 @@
+---
+date: 2022-02-20
+title: Updating NginX TLS settings for 2022
+tags:
+- TLS
+- NginX
+---
+
+My blog (and pretty much every other site I host) is using Let's Encrypt
+certificates in order to be served over https. Using any certificate at all is
+generally an upgrade when it comes to security, but your webserver's
+configuration needs to be up to standard as well. Unlike the Let's Encrypt
+certificates, keeping the configs up to date requires manual intervention, and
+is therefore something I don't do often.
+
+This week I decided I should check up on the state of my SSL configuration in
+nginx. I usually check this through [SSL Lab's SSL Server
+Test](https://www.ssllabs.com/ssltest/analyze.html). This is basically
+[testssl.sh](https://testssl.sh/) in a shiny web frontend, and assigns you a
+score. I aim to always have A or higher, but it seemed my old settings were
+capped at a B. This was due to the cipher list allowing ciphers which are
+nowadays considered insecure.
+
+While I could've just updated the cipher list, I decided to check up on all the
+other settings as well. There's a [GitHub
+gist](https://gist.github.com/gavinhungry/7a67174c18085f4a23eb) which shows you
+what settings to use with nginx to make it secure by modern standards, which
+I've used to check if I should update some of my own settings.
+
+My old settings looked as follows. Please don't be too scared of the giant list
+in the `ssl_ciphers`.
+
+```nginx
+# DHparams
+ssl_dhparam /etc/nginx/dhparam.pem;
+
+# SSL settings
+ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
+ssl_prefer_server_ciphers off;
+ssl_protocols TLSv1.2 TLSv1.3;
+ssl_session_cache shared:le_nginx_SSL:10m;
+ssl_session_tickets off;
+ssl_session_timeout 1440m;
+
+# Additional headers
+add_header Strict-Transport-Security "max-age=63072000" always;
+```
+
+With the new settings, I've added `ssl_buffer_size` and `ssl_ecdh_curve`. A
+friend on IRC pointed out I should enable `ssl_prefer_server_ciphers`, so this
+has been enabled too.
+
+But most notably, the list of `ssl_ciphers` has been dramatically reduced. I
+still allow TLSv1.2 in order to allow slightly older clients to connect without
+any issues, but the ciphers considered *WEAK* have been disabled explicitly.
+This leaves a total of 5 ciphers to use, all of them using ECDHE, so the
+`ssl_dhparam` could be dropped as well.
+
+Lastly, I've added a couple headers for security reasons, as recommended by
+[securityheaders.com](https://securityheaders.com).
+
+```nginx
+# SSL settings
+ssl_protocols TLSv1.3 TLSv1.2;
+
+ssl_buffer_size 4K;
+ssl_ecdh_curve secp521r1:secp384r1;
+ssl_prefer_server_ciphers on;
+ssl_session_cache shared:le_nginx_SSL:2m;
+ssl_session_tickets off;
+ssl_session_timeout 1440m;
+
+ssl_ciphers 'EECDH+AESGCM:EECDH+AES256:!ECDHE-RSA-AES256-SHA384:!ECDHE-RSA-AES256-SHA';
+
+# Additional headers
+add_header Content-Security-Policy "default-src 'self'" always;
+add_header Referrer-Policy "strict-origin-when-cross-origin" always;
+add_header Strict-Transport-Security "max-age=63072000" always;
+add_header X-Content-Type-Options "nosniff" always;
+add_header X-Frame-Options "SAMEORIGIN" always;
+```
+
+{{< admonition title="note" >}}
+I would still like the `ssl_ciphers` to be formatted in a more clean way, which
+I've tried to do with a variable through `set`, but it appears variables are not
+expanded within `ssl_ciphers`. If you have any methods to format the list of
+ciphers used in a cleaner way, I'd be very happy to know!
+{{< / admonition >}}
+
+This configuration is saved as a small snippet which I `include` in all other
+site configurations, so it is updated everywhere at once as well. Now I should
+be able to neglect this for another year or two again.
diff --git a/content/posts/2022/2022-03-05-deprecating-reiserfs.md b/content/posts/2022/2022-03-05-deprecating-reiserfs.md
new file mode 100644
index 0000000..9dcec8d
--- /dev/null
+++ b/content/posts/2022/2022-03-05-deprecating-reiserfs.md
@@ -0,0 +1,74 @@
+---
+date: 2022-03-05
+title: Deprecating ReiserFS
+tags:
+- BTRFS
+- Filesystems
+- GNU+Linux
+- ReiserFS
+- ZFS
+- bcachefs
+---
+
+[ReiserFS is getting deprecated from Linux](https://lkml.org/lkml/2022/2/20/89),
+mostly due to it not being ready for the year 2038. This is a little sad, as I
+still use it on some systems for storing the Gentoo Portage tree, and the Linux
+kernel sources. It works well for this because it supports
+[tail packing](https://en.wikipedia.org/wiki/Block_suballocation#Tail_packing),
+a form of block suballocation, which can save disk space.
+
+So, what alternatives are there for ReiserFS? After asking around and reading
+some comments around the Internet, I've narrowed it down to 3 potential
+candidates, bcachefs, btrfs, and zfs. Each comes with their own pros and cons,
+as things tend to do.
+
+## bcachefs
+
+There are several downsides for bcachefs for me. The first one I found was that
+the documentation on their main site seems a bit lacking, followed shortly by
+finding that there are no ebuilds for it in Gentoo.
+
+Since it was suggested several times on comments on a certain orange site, I
+asked around if it at least supported block suballocation, which is the main
+reason I would want to use it anyway. The answer came back as a "no", so I could
+safely ignore it for the rest of the journey.
+
+## BTRFS
+
+BTRFS seems like a more serious contender. It supports block suballocation, and
+has good enough documentation. As an additional benefit, it is supported in the
+mainline Linux kernel, making it easy to use on any modern setup. There are a
+few issues, such as having to rebalance in certain situations, and this
+rebalancing can itself cause issues. The files I'm storing are relatively easily
+recreated with a single git clone, or downloading a tarball and unpacking that,
+so that doesn't have to be problematic to me.
+
+## ZFS
+
+The final contestant, ZFS, supports block suballocation and has great
+documentation. It is not part of the mainline Linux kernel, however, so this may
+make things more complex on some systems. I run ZFS already on a few machines,
+but not all, so where it is not used already, it is a drawback.
+
+Since my main concern is storing many small files, I created a few logical
+volumes (and 1 ZFS subvol) and cloned the main reason for wanting a filesystem
+with block suballocation, the [Gentoo Portage
+tree](https://github.com/gentoo/portage). The cloning itself was done with
+`--depth=1`.For reference, I also created an ext4 volume.
+
+```
+/dev/mapper/edephas0-test.btrfs 5.0G 559M 3.8G 13% /tmp/test/btrfs
+/dev/mapper/edephas0-test.ext4 4.9G 756M 3.9G 17% /tmp/test/ext4
+/dev/mapper/edephas0-test.reiserfs 5.0G 365M 4.7G 8% /tmp/test/reiserfs
+tyilstore0/test 5.0G 1.1G 4.0G 21% /tmp/test/zfs
+```
+
+Looking at the output from `df -h`, ReiserFS seem to still be a clear winner
+when it comes to storing many small files. Nothing is even close. What does
+surprise me, however, is that ZFS is actually resulting in the largest space
+requirement. I'm not sure why this is, as it should support block suballocation
+just fine according to [the filesystem comparison chart on
+Wikipedia](https://en.wikipedia.org/wiki/Comparison_of_file_systems#Allocation_and_layout_policies).
+
+BTRFS comes out as the next best option, after ReiserFS, so that'll be what I am
+going to use on my systems for storing large trees of small files.
diff --git a/content/posts/2022/2022-04-15-fixing-w-in-tremc.md b/content/posts/2022/2022-04-15-fixing-w-in-tremc.md
new file mode 100644
index 0000000..c434a6e
--- /dev/null
+++ b/content/posts/2022/2022-04-15-fixing-w-in-tremc.md
@@ -0,0 +1,140 @@
+---
+date: 2022-04-15
+title: Fixing ^w in tremc
+tags:
+- Python
+- Transmission
+- tremc
+---
+
+I like collecting GNU+Linux ISOs. I'd like to think I have a pretty serious
+collection of these things. I have a pretty good and stable Internet connection,
+so I collect them in my torrent client, and let them seed pretty much forever,
+so other people can enjoy them too.
+
+For this hobby, I'm using [Transmission](https://transmissionbt.com/), with
+[tremc](https://github.com/tremc/tremc) as the frontend. I've been using it for
+a while, but there's always been a small thing bothering me. Whenever you get a
+prompt to specify the name of the torrent, or the directory to which its
+contents should be downloaded, `^w` immediately kills the entire application.
+
+By regular shell standards, I'm used to `^w` not killing the application, but
+just removing from the cursor to the start of the previous word. I don't often
+change the names of the torrents, but when I do, I often use `^w` to quickly
+remove one or two words in the path. With tremc, this sadly means me killing the
+application, being upset for a little while as I restart it, and hold down the
+backspace for a while to get the intended effect.
+
+Until last night. I set out to read the documentation to fix this issue once and
+for all. I dug into the manual, which specifies that a configuration file at
+`~/.config/tremc/settings.cfg` is read at startup. However, the manual
+doesn't specify anything about the format of this file. There's also no other
+manual pages included in the package.
+
+The Gentoo package specifies a homepage for this project on Github, so I open up
+my least-hated browser and see if there's anything there. Good news, the
+repository contains a sample `settings.cfg`, so I can read that and get an idea
+on how to do keybinds. And the examples do show how to _set_ keybinds. But it
+doesn't seem to be able to _remove_ keybinds. This is kind of a bummer. Setting
+a keybind to an empty value didn't seem to do the trick either. This leaves only
+one option, patching the defaults.
+
+This was actually pretty straightforward, just look for the list of default
+keybinds, and remove a single line.
+
+```patch
+@@ -222,7 +222,6 @@ class GConfig:
+ # First in list: 0=all 1=list 2=details 3=files 4=tracker 16=movement
+ # +256 for RPC>=14, +512 for RPC>=16
+ 'list_key_bindings': [0, ['F1', '?'], 'List key bindings'],
+- 'quit_now': [0, ['^w'], 'Quit immediately'],
+ 'quit': [1, ['q'], 'Quit'],
+ 'leave_details': [2, ['BACKSPACE', 'q'], 'Back to torrent list'],
+ 'go_back_or_unfocus': [2, ['ESC', 'BREAK'], 'Unfocus or back to torrent list'],
+```
+
+Since I'm just testing, and this program is a single Python file, I just edit
+the file in-place, and delay making a proper patch out of for later. Restarting
+tremc, going to the new torrent, pressing `m` (for "move"), and hitting `^w` to
+try and remove a single word, hoping for a quick and easy fix, I was met with
+tremc just quitting again. This was not what I wanted.
+
+So opening up the file again with everyone's favourite editor, I search around
+for the `quit_now` function. Surely that'll bring me closer? The `quit_now`
+string doesn't seem to be used anywhere else, apart from the function that
+defines what the keybind action should do, `action_quit_now`. This seems to
+simply defer to `exit_now`, which leads me to a bit of code with a special case
+to `exit_now` if a certain character is detected. This character appears to be a
+`^w`, which is exactly what I'm trying to stop. So, let's patch that out too.
+
+```patch
+@@ -3760,10 +3759,7 @@ class Interface:
+ self.update_torrent_list([win])
+
+ def wingetch(self, win):
+- c = win.getch()
+- if c == K.W_:
+- self.exit_now = True
+- return c
++ return win.getch()
+
+ def win_message(self, win, height, width, message, first=0):
+ ypos = 1
+```
+
+Restart tremc and test again. Still exiting immediately upon getting a `^w`.
+This bit of code gives me some new insights, it appears `K.W_` is related to the
+keycode of a `^w`. So I continue the search, this time looking for `K.W_`. This
+appears to be used later on to create a list of characters which should act as
+`esc` in certain contexts. Removing the `K.W_` from this is simple enough.
+
+```patch
+@@ -5039,7 +5047,7 @@ def parse_config_key(interface, config, gconfig, common_keys, details_keys, list
+ else:
+ gconfig.esc_keys = (K.ESC, K.q, curses.KEY_BREAK)
+ gconfig.esc_keys_no_ascii = tuple(x for x in gconfig.esc_keys if x not in range(32, 127))
+- gconfig.esc_keys_w = gconfig.esc_keys + (K.W_,)
++ gconfig.esc_keys_w = gconfig.esc_keys
+ gconfig.esc_keys_w_enter = gconfig.esc_keys_w + (K.LF, K.CR, curses.KEY_ENTER)
+ gconfig.esc_keys_w_no_ascii = tuple(x for x in gconfig.esc_keys_w if x not in range(32, 127))
+```
+
+Restart, test, and... Nothing. This is an improvement, the program isn't exiting
+immediately, it just does nothing. I know that `^u` works as I expect, so
+perhaps it needs some love to have `^w` work properly as well. I search for
+`K.U_`, and indeed, there is code dedicated to this keypress, in a long `elif`
+construct. So I add some code to get `^w` working as well. After a bit of
+fiddling, and realizing I've spent way too much time on adding a torrent, I've
+settled on this little bit of love.
+
+```patch
+@@ -3957,6 +3953,18 @@ class Interface:
+ # Delete from cursor until beginning of line
+ text = text[index:]
+ index = 0
++ elif c == K.W_:
++ # Delete from cursor to beginning of previous word... mostly
++ text_match = re.search("[\W\s]+", text[::-1])
++
++ if text_match.span()[0] == 0:
++ # This means the match was found immediately, I can't be
++ # bothered to make this any nicer.
++ text = text[:-1]
++ index -= 1
++ else:
++ text = text[:-text_match.span()[0]]
++ index -= text_match.span()[0]
+ elif c in (curses.KEY_HOME, K.A_):
+ index = 0
+ elif c in (curses.KEY_END, K.E_):
+```
+
+It looks for the first non-word character or a space, starting from the end of
+the string (`[::-1]` reverses a string in Python). The resulting `Match` object
+can tell me how many characters I need to delete in the `.span()[0]` value. A
+small exception is created if that value is `0`, otherwise the logic below
+doesn't work well.
+
+It's not perfect, but it gets the job done well enough, and I don't like Python
+enough to spend more time on it than I've already done. I am open for better
+solutions that work better, though!
diff --git a/content/posts/2022/2022-04-23-a-cookbook.md b/content/posts/2022/2022-04-23-a-cookbook.md
new file mode 100644
index 0000000..e86fcda
--- /dev/null
+++ b/content/posts/2022/2022-04-23-a-cookbook.md
@@ -0,0 +1,52 @@
+---
+date: 2022-04-23
+title: A cookbook!
+tags:
+- Food
+---
+
+Last week, I've decided to add a cookbook to my website. I've thought about
+doing so for a while, but was rather hesitent since my website was mostly a
+tech-minded blog. However, this time around I've decided to simply add a
+cookbook, and have seperate RSS feeds for my [blog posts](/posts/index.xml) and
+[recipes](/recipes/index.xml), so that readers can decide what they want to
+follow. Now I can easily share any recipes that visitors have asked me to share
+over the years.
+
+The cookbook has an overview of all recipes, and each invidual recipe has a
+layout greatly inspired by MartijnBraam's [FatHub](https://fathub.org). The
+JavaScript is an exact copy, even.
+
+The format of the recipes has been altered slightly. I found the FatHub format
+to be a little too verbose to make it simple enough to want to write down the
+recipes. So I've trimmed down on some of that. You can check the sources that I
+use on [git.tyil.nl](https://git.tyil.nl/blog/).
+
+Since my website is generated with [Hugo](https://gohugo.io), I had to do the
+template myself as well. But these were fairly simple to port over, and I am
+fairly happy with the result. I've made two changes compared to the layout used
+by FatHub: Every step in the instructions is numbered, and the checkboxes for
+the ingredients are at the left-hand side. The ingredients don't contain a
+preparation step in the tables, as I've made that part of the cooking
+instructions.
+
+The entire thing was done in an afternoon during Easter, so it was pretty
+straightforward to set up. I haven't included many recipes yet, as I want to
+double-check the right amounts of ingredients and instructions for many of them.
+The downside of a recipe is that people generally follow it to the letter, and
+I'm not a professional cook, I often cook just by tasting and adjusting as
+desired.
+
+There's one thing I didn't include, but which I might consider working on in the
+future: [baker's percentages](https://en.wikipedia.org/wiki/Baker_percentage).
+Some of my recipes have been written down in this notation, and for now I'll be
+converting them to regular quantities instead. There's also some downsides to
+baker's percentages such as harder to calculate what a serving size is, or the
+duration of certain steps, which has caused me to not make this a hard
+requirement for the cookbook section of my site.
+
+I think the cookbook is more than enough to get started with, and to try sharing
+some recipes in. If I've ever cooked something for you in person, and you would
+like to know the recipe, don't hesitate to ask me to include it in the cookbook.
+Additionally, if you have some tips on how to improve an existing recipe, I'd be
+very happy to hear about it!
diff --git a/content/posts/2022/2022-05-07-bashtard-introduction.md b/content/posts/2022/2022-05-07-bashtard-introduction.md
new file mode 100644
index 0000000..0f93fdd
--- /dev/null
+++ b/content/posts/2022/2022-05-07-bashtard-introduction.md
@@ -0,0 +1,265 @@
+---
+title: Configuring my Machines with Bashtard
+date: 2022-05-07
+tags:
+- Bash
+- Bashtard
+- FreeBSD
+- GNU+Linux
+- Programming
+---
+
+Over the past couple weeks I've been spending some time here and there to work
+on my own application for configuring my machines. Before this I've tried
+Ansible, but found it to be very convoluted to use, and requires a lot of
+conditionals if your machines aren't all running the same base system.
+
+So I made something in Bash, with a few abstractions to make certain
+interactions less annoying to do manually every time. This used to be called
+`tyilnet`, but I've discussed the setup with a few people on IRC, and decided it
+would be a fun project to make it a bit more agnostic, so other people could
+also easily start using it. This resulted in the creation of
+[Bashtard](https://git.tyil.nl/bashtard/), pronounced as "bash", followed by
+"tard" (as in "bastard").
+
+It works by simply writing Bash scripts to do the configuration, and provides
+abstractions for using the system's package manager, service manager, and some
+utilities such as logging and dealing with configured values. Configuration
+values can be set on a per-host or per-OS basis. Since I run a varied base of
+OSs, including Gentoo, Debian, and FreeBSD, the per-OS configuration comes in
+very handy to me.
+
+As for the reason to use Bash, I chose it because most of the systems I run
+already have this installed, so it doesn't add a dependency _most of the time_.
+I would've liked to do it in POSIX sh, but I feel that when you're reaching a
+certain level of complexity, Bash offers some very nice features which can make
+your code cleaner, or less likely to contain bugs. Features such as `[[ ]]`,
+`local`, and arrays come to mind.
+
+I've been kindly asked to guide potential new users to writing their first
+Bashtard script, known as a _playbook_, so if you want to know about how it
+works in practice, keep on reading. If you're satisfied with your current
+configuration management system, this might not be quite as interesting to you,
+so be warned.
+
+The first steps for a new user would obviously to install Bashtard, as it's not
+in any OSs package repositories yet. A `Makefile` is supplied in the repository,
+which should make this easy enough.
+
+```txt
+git clone https://git.tyil.nl/bashtard
+cd bashtard
+sudo make install
+hash -r
+```
+
+Once installed, it needs some initialization.
+
+```txt
+bashtard init
+```
+
+This will create the basic structure in `/etc/bashtard`, including a
+`playbooks.d`. Inside this `playbooks.d` directory, any directory is considered
+to be a playbook, which requires a `description.txt` and a `playbook.bash`.
+
+```txt
+cd /etc/bashtard/playbooks.d
+mkdir ssh
+cd ssh
+echo "OpenSSH configuration" > description.txt
+$EDITOR playbook.bash
+```
+
+The `playbook.bash` needs to contain 3 functions which are used by `bashtard`, a
+`playbook_add()`, `playbook_sync()`, and `playbook_del()`. These will be called
+by the `bashtard` subcommand `add`, `sync`, and `del` respectively.
+
+I generally start with the `playbook_sync()` function first, since this is the
+function that'll ensure all the configurations are kept in sync with my desires.
+I want to have my own `sshd_config`, which needs some templating for the
+`Subsystem sftp` line. There's a `file_template` function provided by bashtard,
+which does some very simple templating. I'll pass it the `sftp` variable to use.
+
+```bash
+playbook_sync() {
+ file_template sshd_config \
+ "sftp=$(config "ssh.sftp")" \
+ > /etc/ssh/sshd_config
+}
+```
+
+Now to create the actual template. The `file_template` function looks for
+templates in the `share` directory inside the playbook directory.
+
+```txt
+mkdir share
+$EDITOR share/sshd_config
+```
+
+Since I already know what I want my `sshd_config` to look like from previous
+installed systems, I'll just use that, but with a variable for the `Subsystem
+sftp` value.
+
+```cfg
+# Connectivity
+Port 22
+AddressFamily any
+ListenAddress 0.0.0.0
+ListenAddress ::
+
+# Fluff
+PrintMotd yes
+
+# SFTP
+Subsystem sftp ${sftp}
+
+# Authentication
+AuthorizedKeysFile /etc/ssh/authorized_keys .ssh/authorized_keys
+PermitRootLogin no
+PasswordAuthentication no
+ChallengeResponseAuthentication no
+PubkeyAuthentication no
+
+# Allow tyil
+Match User tyil
+ PubkeyAuthentication yes
+
+# Allow public key authentication over VPN
+Match Address 10.57.0.0/16
+ PubkeyAuthentication yes
+ PermitRootLogin prohibit-password
+```
+
+The `${sftp}` placeholder will be filled with whatever value is returned by
+`config "ssh.sftp"`. And for this to work properly, we will need to define the
+variable somewhere. These are written to the `etc` directory inside a playbook.
+You can specify defaults in a file called `defaults`, and this can be
+overwritten by OS-specific values, which in turn can be overwritten by
+host-specific values.
+
+```txt
+mkdir etc
+$EDITOR etc/defaults
+```
+
+The format for these files is a very simple `key=value`. It splits on the first
+`=` to determine what the key and value are. This means you can use `=` in your
+values, but not your keys.
+
+```txt
+ssh.sftp=/usr/lib/openssh/sftp-server
+```
+
+This value is correct for Debian and derivatives, but not for my Gentoo or
+FreeBSD systems, so I've created OS-specific configuration files for these.
+
+```txt
+mkdir etc/os.d
+cat etc/os.d/linux-gentoo
+ssh.sftp=/usr/lib64/misc/sftp-server
+```
+
+```txt
+cat etc/os.d/freebsd
+ssh.sftp=/usr/lib64/misc/sftp-server
+```
+
+My `sshd_config` template also specifies the use of a `Motd`, so that needs to
+be created as well. This can again be done using the `template` function.
+
+```bash
+file_template "motd" \
+ "fqdn=${BASHTARD_PLATFORM[fqdn]}" \
+ "time=$(date -u "+%FT%T")" \
+ > /etc/motd
+```
+
+The `motd` template gets saved at `share/motd`.
+
+```txt
+ ████████╗██╗ ██╗██╗██╗ ███╗ ██╗███████╗████████╗
+ ╚══██╔══╝╚██╗ ██╔╝██║██║ ████╗ ██║██╔════╝╚══██╔══╝
+ ██║ ╚████╔╝ ██║██║ ██╔██╗ ██║█████╗ ██║
+ ██║ ╚██╔╝ ██║██║ ██║╚██╗██║██╔══╝ ██║
+ ██║ ██║ ██║███████╗██╗██║ ╚████║███████╗ ██║
+ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝╚═╝ ╚═══╝╚══════╝ ╚═╝
+
+Welcome to ${fqdn}, last updated on ${time}.
+```
+
+Lastly, we want to ensure the SSH daemon gets reloaded after every sync, so
+let's add that to the `playbook_sync()` function as well.
+
+```bash
+svc reload "sshd"
+```
+
+The `svc` utility looks for a configuration value that starts with `svc.`,
+followed by the service you're trying to act upon, so in this case that would be
+`svc.sshd`. We can add this to our configuration files in `etc`. Across all my
+machines, `sshd` seems to work as the value, so I only need to add one line to
+`etc/defaults`.
+
+```txt
+svc.sshd=sshd
+```
+
+This should take care of all the things I want automatically synced. The
+`playbook_add()` function is intended for all one-time setup required for any
+playbook. In this case that means the SSH daemon's service needs to be
+activated, since it is not active by default on all my setups.
+
+```bash
+playbook_add() {
+ svc enable "sshd"
+ svc start "sshd"
+}
+```
+
+However, `add` does not call a `sync`, and I don't want my SSH service to run
+with default configuration until a `sync` is initialized. So before enabling and
+starting the service, I will call `sync` manually, by running a `playbook_sync`
+first. This in turn, however, poses another problem, as `playbook_sync()` wants
+to reload the service, which it can't do unless it is already running. To fix
+this, I'll add an `if` statement to skip reloading if `bashtard` is running the
+`add` command.
+
+```bash
+playbook_add() {
+ playbook_sync
+
+ svc enable "sshd"
+ svc start "sshd"
+}
+
+playbook_sync() {
+ ...
+
+ [[ $BASHTARD_COMMAND == "add" ]] && return
+
+ svc reload "sshd"
+}
+```
+
+Now, `bashtard add sshd` will run the `playbook_add()` function, which calls the
+`playbook_sync()` function before enabling and starting the `sshd` service. All
+that is left is the `playbook_del()` function, which only really needs to stop
+and disable the service. The templated files can be removed here as well if
+desired, of course.
+
+```bash
+playbook_del() {
+ svc stop "sshd"
+ svc disable "sshd"
+}
+```
+
+Lastly, I configured my `crond` to run `bashtard sync` every 20 minutes, so
+whenever I update my configurations, it can take up to 20 minutes to propagate
+to all my machines. Having an abstraction to deal with `cron` (or SystemD timers
+where applicable) in Bashtard is something I'd like to add, but I have no
+concrete plans on how to do this, yet.
+
+You can find the full `playbook.bash` source on
+[git.tyil.nl](https://git.tyil.nl/tyilnet/tree/playbooks.d/ssh/playbook.bash?id=319ab064370cb1e65be115ffddf5c0cd519af2dd).
diff --git a/content/posts/2022/2022-08-06-installing-gentoo-encrypted-zfs-efistub.md b/content/posts/2022/2022-08-06-installing-gentoo-encrypted-zfs-efistub.md
new file mode 100644
index 0000000..2825b7c
--- /dev/null
+++ b/content/posts/2022/2022-08-06-installing-gentoo-encrypted-zfs-efistub.md
@@ -0,0 +1,242 @@
+---
+date: 2022-11-20
+title: "Installing Gentoo with encrypted ZFS rootfs and EFIstub kernel"
+tags:
+- GNU+Linux
+- Gentoo
+- Tutorial
+- ZFS
+---
+
+A little while ago, I got a new work laptop. As is customary, I installed my
+preferred GNU+Linux environment onto it. Consequently, a few people have asked
+me to detail my steps to get this system up and running, as they would like to
+try out a similar setup as I did. It's also been a while since I made another
+blog post, so here's killing two birds with one stone!
+
+## Preparing disks
+
+Make sure you get the right device name, or you'll purge the data on some other
+drive!
+
+```sh
+parted -a optimal /dev/nvme1n1
+mklabel gpt
+mkpart esp 1 5130
+mkpart rootfs 5130 -1
+set 1 boot on
+quit
+```
+
+### Get IDs of partitions
+
+For partitioning I've lately come to love using disk IDs, rather than their
+`/dev/sd*` entries. They're easy to look up, so copy them over to use them later
+on.
+
+```sh
+ls -l /dev/disk/by-id
+```
+
+- `nvme-eui.36483331545090280025385800000001-part1` -> ESP
+- `nvme-eui.36483331545090280025385800000001-part2` -> ZFS
+
+### Formatting
+
+#### ESP
+
+The ESP partition holds the kernel and initramfs, and _must_ be FAT32.
+
+```sh
+mkfs.vfat -F32 /dev/disk/by-id/nvme-eui.36483331545090280025385800000001-part1
+```
+
+#### zpool
+
+The zpool settings used here are the settings I used. You should verify these
+settings also work optimally for your setup! I generally name my pools after the
+device they're running from, in this case `ivdea`. Any name will work here, just
+make sure to be consistent later down the guide!
+
+```sh
+rm -f /etc/hostid && zgenhostid
+
+zpool create -f \
+ -O acltype=posixacl \
+ -O compression=lz4 \
+ -O dedup=off \
+ -O encryption=aes-256-gcm \
+ -O keyformat=passphrase \
+ -O keylocation=prompt \
+ -O relatime=on \
+ -O xattr=sa \
+ -R /mnt/gentoo \
+ -m none \
+ -o ashift=12 \
+ -o cachefile=/etc/zfs/zpool.cache \
+ ivdea0 \
+ /dev/disk/by-id/nvme-eui.36483331545090280025385800000001-part2
+
+zfs create -o mountpoint=none ivdea0/rootfs
+zfs create -o mountpoint=/ ivdea0/rootfs/gentoo
+zfs create -o mountpoint=none ivdea0/rootfs/gentoo/usr
+zfs create -o mountpoint=none ivdea0/rootfs/gentoo/var
+zfs create -o mountpoint=none ivdea0/rootfs/gentoo/var/lib
+zfs create -o mountpoint=none ivdea0/home
+zfs create -o mountpoint=/home/tyil ivdea0/home/tyil
+
+zpool set bootfs=ivdea0/rootfs/gentoo ivdea0
+```
+
+## Preparing chroot
+
+You will want to grab the latest Gentoo autobuild tarball for your architecture.
+I'm _not_ using systemd, if you do desire this for some reason, you may need to
+alter some steps.
+
+### Initial
+
+```sh
+cd /mnt/gentoo
+mkdir efi
+mount /dev/disk/by-id/nvme-eui.36483331545090280025385800000001-part1 efi
+wget $STAGE3 # Use whichever URL for the stage3 tarball you need
+tar xpf stage3*.tar.xz --xattrs-include='*.*' --numeric-owner
+```
+
+### Recovery
+
+This section is labeled "Recovery" to easily find it later, in case you need to
+go back into the chroot to fix up any issues that prevent you from booting it.
+
+```sh
+mkdir -p etc/zfs
+cp /etc/zfs/zpool.cache etc/zfs
+cp --dereference /etc/resolv.conf /mnt/gentoo/etc/
+mount -t proc /proc proc
+mount --rbind --make-rslave /sys sys
+mount --rbind --make-rslave /dev dev
+mount --rbind --make-rslave /run run
+chroot . /bin/bash -l
+```
+
+## Configuring the system
+
+The base system is now installed, and most of the following steps are for
+configuring it to actually work properly.
+
+### Portage
+
+Run the initial Portage tree download. This will use `webrsync`, you can
+configure it to use `git` at a later stage if desired.
+
+```sh
+mkdir -p /etc/portage/repos.conf
+cp /usr/share/portage/config/repos.conf /etc/portage/repos.conf/gentoo.conf
+emerge-webrsync
+```
+
+### Editor
+
+Ofcourse, you can stick to `nano`, but I've been a vim guy for a very long time
+now, and without it I feel sad. It is the first thing I install, to make the
+rest of the configuration easier to do, by virtue of having the best editor
+available.
+
+```sh
+emerge vim
+```
+
+Once `vim` (or whichever worse editor you prefer) is installed, you can go
+around editing configuration files as needed.
+
+### locale
+
+Enable all the locales you desire in `/etc/locale.gen`. Once all the desird
+locales are uncommented, you can generate the locales with `locale-gen`. You
+will most likely also want to add the locales to the `L10N` variable in your
+`make.conf`.
+
+### timezone
+
+Set your timezone by making `/etc/localtime` a symlink to the timezone you use.
+
+```sh
+ln -fs /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime
+```
+
+### hostname
+
+Set the machine's short hostname in `/etc/conf.d/hostname` first, then add your
+hostname aliases to `/etc/hosts`.
+
+```txt
+# /etc/conf.d/hostname
+hostname="ivdea"
+
+# /etc/hosts
+127.0.0.1 ivdea.tyil.net ivdea
+::1 ivdea.tyil.net ivdea
+```
+
+### kernel
+
+{{< admonition title="Note" >}}
+This will build the initramfs twice, since emerging gentoo-kernel will build it
+automagically. This can be "fixed" by removing a USE flag, but this is easier to
+me.
+{{</ admonition >}}
+
+By the time you're reading this, the kernel version used here is probably
+outdated. You will want to update it to whichever kernel version you're going to
+use.
+
+```sh
+emerge \
+ busybox \
+ dracut \
+ efibootmgr \
+ gentoo-kernel \
+ intel-microcode \
+ linux-firmware
+
+emerge sys-fs/zfs-kmod sys-fs/zfs
+emerge --config gentoo-kernel
+
+rc-update add zfs-import boot
+rc-update add zfs-mount boot
+rc-update add zfs-share default
+rc-update add zfs-zed default
+
+zgenhostid
+
+cp /boot/vmlinuz-5.15.59-gentoo-dist /efi/efi/gentoo/vmlinuz-5.15.59-gentoo-dist.efi
+cp /boot/initramfs-5.15.59-gentoo-dist /efi/efi/gentoo/initramfs-5.15.59-gentoo-dist.img
+
+efibootmgr \
+ --disk /dev/disk/by-id/nvme-eui.36483331545090280025385800000001 \
+ --part 1 \
+ --create \
+ --label "Gentoo ZFS 5.15.59" \
+ --loader 'efi\gentoo\vmlinuz-5.15.59-gentoo-dist.efi' \
+ --unicode \
+ 'dozfs root=ZFS=ivdea0/rootfs/gentoo ro initrd=\efi\gentoo\initramfs-5.15.59-gentoo-dist.img encrypted'
+```
+
+### Root password
+
+Set the root password using `passwd`. This would also be a good time to add any
+other users you want to use, and configure them with the correct permissions and
+groups.
+
+## Misc
+
+If you have any other software requirements, such as wireless network management
+or privilege escalation utilities, this is the most appropriate time to install
+and configure them.
+
+## Reboot
+
+Now you can reboot into the system, and be done with this guide. If anything
+isn't working properly, return to the "Recovery" step and fix any outstanding
+issues.
diff --git a/content/posts/2022/_index.md b/content/posts/2022/_index.md
new file mode 100644
index 0000000..3bf91c1
--- /dev/null
+++ b/content/posts/2022/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2022
+---
diff --git a/content/posts/2023/2023-02-23-the-woes-of-awsvpnclient.md b/content/posts/2023/2023-02-23-the-woes-of-awsvpnclient.md
new file mode 100644
index 0000000..a852793
--- /dev/null
+++ b/content/posts/2023/2023-02-23-the-woes-of-awsvpnclient.md
@@ -0,0 +1,91 @@
+---
+date: 2023-02-23
+title: The Woes of AWSVPNClient
+tags:
+- Amazon
+- AWS
+- AWSVPNClient
+---
+
+For my current `$dayjob` I am required to start using the AWS VPN Client. This
+is not a problem per se, however, this piece of software has given me some
+particular headaches. In this post, I want to air some frustrations that it has
+brought me in the past two days, trying to get this software working properly
+on Debian.
+
+## GNU+Linux Support
+
+The AWS VPN Client has gotten an official client for GNU+Linux users. Not all
+of them, sadly, they specifically support Ubuntu 18.04. I find it important to
+note that this is 2 LTS versions behind the current Ubuntu version 22.04. Apart
+from that, only Ubuntu is rather limited. Amazon isn't a small company, and
+they should be able to support various distributions.
+
+In general I would recommend to support the upstream distribution, which in
+this case would be Debian. This would ensure that it becomes available on
+Ubuntu by virtue of it being Debian based.
+
+That said, only Ubuntu packages wouldn't be a huge problem if not for the next
+issue I have with this software...
+
+## Proprietary Software
+
+The code for this application is private, and Amazon has no intention to change
+this. There's nothing very special about the application, it's just a
+proprietary wrapper around OpenVPN, so in my mind I find it hard to believe
+that they're trying to "protect" anything sensitive. It feels like a simple
+move to instill the idea that you're highly dependent on them.
+
+If they _were_ to make this software free (as in freedom), packaging could be
+done by package maintainers, or really just anyone who feels like doing it.
+This would remove a burden on Amazon, and ensure better availability for all
+potential users.
+
+Additionally, it would make debugging issues much easier. Because...
+
+## Logging
+
+The logging the application does is pathetic. There's a lot of duplicated logs
+that are spammed hundreds of times per second. Tailing your logs can also be
+more annoying than it needs to be, since the client rotates which file it logs
+to every 1048629 bytes.
+
+I currently have 30 log files, generated by two sessions. In these log files,
+the line `[INF] Begin receive init again` appears 509114 times. Over _half a
+million_ times. The total number of log lines in all these log files is 510394,
+meaning only 1280 lines are something different.
+
+Of those 1280 lines, the logs themselves aren't much better. I apparently had
+to install `systemd-resolved` in order to fix the following error:
+
+```txt
+2023-02-23 10:02:50.870 +01:00 [DBG] CM received: >LOG:1677142970,F,WARNING: Failed running command (--up/--down): external program exited with error status: 1
+>FATAL:WARNING: Failed running command (--up/--down): external program exited with error status: 1
+
+2023-02-23 10:02:50.870 +01:00 [DBG] CM processsing: >LOG:1677142970,F,WARNING: Failed running command (--up/--down): external program exited with error status: 1
+2023-02-23 10:02:50.870 +01:00 [DBG] CM processsing: >FATAL:WARNING: Failed running command (--up/--down): external program exited with error status: 1
+2023-02-23 10:02:50.870 +01:00 [DBG] Fatal exception occured
+2023-02-23 10:02:50.870 +01:00 [DBG] Stopping openvpn process
+2023-02-23 10:02:50.870 +01:00 [DBG] Sending SIGTERM to gracefully shut down the OpenVPN process
+2023-02-23 10:02:50.871 +01:00 [DBG] Invoke Error
+2023-02-23 10:02:50.871 +01:00 [DBG] DeDupeProcessDiedSignals: OpenVPN process encountered a fatal error and died. Try connecting again.
+```
+
+It is not particularly clear this fails due to not having `systemd-resolved`
+installed and running. The `.deb` provided by Amazon does not even depend on
+`systemd-resolved`!
+
+Another gripe I've had with the logs is their location. It saves these in
+`~/.config/AWSVPNClient/logs`. It may seem weird since this path contains a
+directory named `.config`, and indeed, this is not a great place to store logs.
+The [XDG Base Directory
+Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
+specifies `$XDG_STATE_HOME`, with one explicit example for it being logs.
+However, for this to make sense, the application needs to respect the `XDG_*`
+values to begin with, which it currently doesn't.
+
+## All in all
+
+This software is pretty bad, but if it were free software, at least the users
+could improve it to suck less, and easily introduce support for various
+additional platforms. Instead, we're just stuck with a piece of bad software.
diff --git a/content/posts/2023/2023-03-08-using-laminar-for-selfhosted-ci.md b/content/posts/2023/2023-03-08-using-laminar-for-selfhosted-ci.md
new file mode 100644
index 0000000..7158ed1
--- /dev/null
+++ b/content/posts/2023/2023-03-08-using-laminar-for-selfhosted-ci.md
@@ -0,0 +1,64 @@
+---
+date: 2023-03-08
+title: Using Laminar for Self-hosted CI
+tags:
+- Bash
+- CI
+- Git
+- GNU+Linux
+---
+
+I've hosted my [own git repositories](https://git.tyil.nl) for quite a while,
+but I hadn't found a simple self-hosted CI solution yet. I've tried several,
+and found them to be a bit too cumbersome to setup and actually put to use. The
+majority requires you to host a full "git forge", such as GitLab or Gitea, in
+order to use their webhook functionality in order to trigger a CI build. This
+didn't seem worth the effort to me, so I kept looking for an alternative that
+worked well for me.
+
+I think I've finally found one in [Laminar](https://laminar.ohwg.net/), after a
+suggestion from a friend on the Fediverse. I do wonder how I could've spent so
+much time searching without ever finding this solution!
+
+Laminar itself was easy to install from source, but another person chimed in to
+let me know they already made an `ebuild` for it, which is available in their
+overlay, making it even easier for me to try out. A single `emerge laminar`,
+and a couple seconds of building it, and I was ready to start trying it out.
+
+Configuration of jobs is done through scripts in whichever language you prefer,
+giving you quite a bit of power. The documentation seems to mostly use Bash,
+and that seemed to be a logical choice for me too, so that's what I've been
+playing with as well.
+
+Running jobs itself is as easy as `laminarc queue <name>`. It can't be much
+simpler, and this CLI interface makes it very easy to start a new job from a
+git `post-receive` hook. I wrote one which also shows the URL of the job's logs
+whenever I push new comments to [the Bashtard
+repository](https://git.tyil.nl/bashtard/about/).
+
+{{<highlight bash>}}
+while read old new ref
+do
+ laminarc queue bashtard \
+ "GIT_BRANCH=$ref" \
+ "GIT_COMMIT=$new" \
+ | awk -F: '{ print "https://ci.tyil.nl/jobs/"$1"/"$2 }'
+done
+{{</highlight>}}
+
+Using this, I can verify a job started, and immediately go to the page that
+shows the logs. I plan to use Laminar's post-job script to leverage `ntfy` to
+send me a notification on failed builds.
+
+Since all the worthwhile configuration for Laminar is just plain text, it is
+also very easy to manage in your preferred configuration management system,
+which is also something I plan to do in the nearby future.
+
+One slight annoyance I have so far is that I can't use (sub)directories for all
+the job scripts. Since I don't have many yet, this isn't a real problem yet,
+but it could pose a minor issue in the far future once I've written more job
+scripts.
+
+Given that that's the only "issue" I've found thus far, after a couple days of
+playing with it, I'd highly recommend taking a look at it if you want to set up
+a CI system for your self-hosted git repositories!
diff --git a/content/posts/2023/2023-03-26-finally-templating-bashtard.md b/content/posts/2023/2023-03-26-finally-templating-bashtard.md
new file mode 100644
index 0000000..b80270c
--- /dev/null
+++ b/content/posts/2023/2023-03-26-finally-templating-bashtard.md
@@ -0,0 +1,86 @@
+---
+date: 2023-03-29
+title: Finally, Templating in Bashtard!
+tags:
+- Bash
+- Bashtard
+- FreeBSD
+- GNU+Linux
+---
+
+In the past year, I've written Bashtard, a simple configuration system written
+in Bash to minimize the required dependencies, and to have a better system to
+handle different distributions/OSs in your cluster. Especially the past two
+months I've done quite a bit of work on it. I've worked out how to do reusable
+playbooks, generate a usable Debian package from the Makefile, extend the
+supported platforms, and more. And now, I've finally found a library to improve
+templating functionality, [Bash Pure Template](https://github.com/husixu1/bpt).
+
+When I originally started Bashtard I had looked around for nice and simple
+templating solutions that I could use. Sadly, pretty much all the available
+results required me to add dependencies, or couldn't really do more than what I
+did using `sed` and `awk`.
+
+For a long time, I had accepted that the kind of system that I wanted didn't
+exist, and I wasn't interested in making it myself at the time. Last night,
+however, I decided to just give it a quick search to see if anything had
+changed, and BPT popped up somewhere in my results. Having a quick look through
+the documentation made me very interested, it seemed to have all the features I
+desired, while still sticking to utilities I've already accepted for Bashtard.
+
+With one small exception, `md5sum`. This utility is not available on the FreeBSD
+systems I maintain. On FreeBSD, this tool is called `md5`, and has different
+options it can use. On the bright side, both `md5sum` and `md5` accept the
+content to be hashed on `STDIN`, and will write the hash to `STDOUT`.
+Additionally, Bashtard already contains logic to deduce what kind of system it
+is running on.
+
+And so I decided it's worth a try. There's only 5 references to `md5sum`, and
+the all happen in the same function, `bpt.fingerprint`. I've added an extra
+variable, `util`, and a `case...esac` to set this variable.
+
+```bash
+local util
+
+case "${BASHTARD_PLATFORM[key]}" in
+ freebsd) util=md5 ;;
+ linux-*) util=md5sum ;;
+ *)
+ debug "bpt/fingerprint" "Falling back to md5sum for hashing"
+ util=md5sum
+ ;;
+esac
+```
+
+After that, just replace all the `md5sum` invocations with `"$util"`. And a
+quick test later, it seems to function just fine. Implementing BPT as a library
+was incredibly straightforward too.
+
+```bash
+. "$BASHTARD_LIBDIR/vendor/bpt.bash"
+
+file_template_bpt()
+{
+ local file
+
+ file="$1" ; shift
+
+ eval "$* bpt.main ge \"$file\""
+}
+```
+
+The `eval` is a bit icky, but it saves me from polluting the environment
+variables through various `export`s.
+
+Another small adjustment I've made to BPT is the shebang. Upstream uses
+`#!/bin/bash`, but this is incorrect on some systems, including FreeBSD. It uses
+`#!/usr/bin/env bash` in the Bashtard version. Additionally, the upstream
+repository uses `.sh` as the file extension, which I've updated to be `.bash` to
+more accurately reflect which shell it is used with. Upstream also uses a
+4-space indent, which I've left as-is for now, since indentation is more of a
+personal choice, even if that choice is wrong. Finally, I added 3 `shellcheck
+disable` rules to make shellcheck happy.
+
+After some playbook testing on my own systems, I can say that BPT works pretty
+well so far, and I'm very glad the author made it available as free software.
+Thanks!
diff --git a/content/posts/2023/2023-05-23-bashtard-2.0.0.md b/content/posts/2023/2023-05-23-bashtard-2.0.0.md
new file mode 100644
index 0000000..654435f
--- /dev/null
+++ b/content/posts/2023/2023-05-23-bashtard-2.0.0.md
@@ -0,0 +1,110 @@
+---
+date: 2023-05-23
+title: Bashtard v2.0.0
+tags:
+- Bash
+- Bashtard
+- FreeBSD
+- GNU+Linux
+---
+
+A little over a year ago I started on a project to create my own configuration
+management system. I've been disappointed with existing alternatives, such as
+Ansible, on the grounds that they don't work all that well if you have a mix of
+different distros with different package managers, and sometimes even different
+paths to store data in.
+
+I've been having a lot of fun working on it, since the limitations I've put on
+it result in having to solve some problems in different ways than I would in a
+full-fledged programming language. These limitations also keep things pretty
+simple, and ensure that most of the features I have worked on need little to no
+additional effort to run on all the different systems I use for my computing
+needs.
+
+And now, a year later, I feel confident enough about a new release. There's some
+small backwards incompatible changes, so a new major release version is the way
+to go. [Bashtard v2.0.0](https://www.tyil.nl/projects/bashtard/releases/2.0.0/)
+is now available. There are a few big things that I want to go into a little
+bit, but you can also find a full list of changes in the changelog included on
+the release page.
+
+# Templating
+
+After using the templating features I [wrote about]() last month, I've decided
+to _not_ include it into Bashtard. I am not convinced after using it in practice
+that it adds enough value to warrant the size of the added code, and hassling
+with two licenses instead of one. I am still very much open to the idea of a
+good base templating engine, but for now you can always install `jinja2` or
+something on the target machine, and call that manually. The new
+`playbook_path()` function should make it easy to generate the path to your
+playbook's files.
+
+# Additional `$BASHTARD_*` vars
+
+Apart from having a new key in `$BASHTARD_PLATFORM` called `init`, there's a
+completely new variable in this version: `$BASHTARD_PLAYBOOK_VARS`. Currently,
+it's only used to set a given variable as required, but can be extended in the
+future with other kinds of checks. This allows playbooks to define some data to
+be required for it to run, and have it refuse to run if those are not supplied,
+rather than having to manually check them when the playbook runs. This is mainly
+intended for use with playbooks you intend to share, so that other people can
+get reasonable feedback as to what they _need_ to configure, vs what they _can_
+configure.
+
+# Re-usable playbooks
+
+So let's talk about one of the more important updates to Bashtard. At least, in
+my opinion. How playbooks are being used has been altered slightly, in order to
+allow a little easier re-use of them. I consider this a very important feature
+of any configuration management system, the ability to share your playbooks with
+others easily, and being able to use other people's playbooks with minimal
+effort. This greatly reduces the barrier to get started, and encourages people
+to show off what they've made.
+
+The current implementation is built upon git submodules, and the `bashtard pull`
+command will take them into account. Perhaps I'll add an `import` subcommand in
+the future to abstract the git submodule effort away, as I know that many people
+find it difficult to work with. However, since `git` is already ingrained in
+Bashtard, this addition keeps dependencies low, and allows me to keep the
+complexity out of the Bash code.
+
+# data.d
+
+Having re-usable playbooks introduced the need to have a place for data that is
+important to my setup, but completely useless to someone else's setup. For this,
+the `data.d` directory was added. You can store information that should be
+preserved across sync runs on your machines, but are not a good fit to keep in
+the actual playbook itself. I personally use it for my
+[`vpn-tinc`](https://git.tyil.nl/bashtard/vpn-tinc/) playbook to keep the host
+files in.
+
+Another use-case for this directory is without a playbook at all. You can put a
+regular directory in it, and symlink to it from a host system to keep a given
+directory in sync across all your machines. In my case, I have an `etc-nixos`
+directory in my `data.d` directory. On my NixOS system I have a symlink from
+`/etc/nixos` to `/etc/bashtard/data.d/nixos`. If I ever continue with NixOS, I
+can have this on all systems, and share any `.nix` files across all machines.
+
+# Binary packages!
+
+Lastly, I've [written
+about](https://www.tyil.nl/post/2023/03/08/using-laminar-for-self-hosted-ci/)
+Laminar before. I'm still using it, and I'm still very happy with its
+simplicity. Since setting it up I've added jobs to verify my Bashtard code with
+`shellcheck`, and if it passes, it'll queue up additional jobs to create a
+`.tar.gz` distribution and a `.deb` distribution. I hope to expand this to also
+generate binaries for use with Alpine, FreeBSD, and Archlinux. I've recently set
+up an S3-compatible object storage,
+
+Additionally, I've recently set up an S3-compatible object store, which Laminar
+should push such artifacts to immediately. This will simplify new releases of
+any software, and offload this kind of storage to an actual remote server,
+rather than hosting `dist.tyil.nl` directly from my desktop.
+
+# Wrapping up
+
+All in all, I've been very happy with Bashtard so far, and I've been having a
+_lot_ of fun working on it. I hope to be able to continue working on it and
+making it even better that it is in this release.
+
+Thanks for reading, and perhaps even using Bashtard!
diff --git a/content/posts/2023/2023-07-13-getting-emoji-to-work-in-kde-on-debian.md b/content/posts/2023/2023-07-13-getting-emoji-to-work-in-kde-on-debian.md
new file mode 100644
index 0000000..a5b0980
--- /dev/null
+++ b/content/posts/2023/2023-07-13-getting-emoji-to-work-in-kde-on-debian.md
@@ -0,0 +1,138 @@
+---
+date: 2023-07-13
+title: Getting Emoji to Work in KDE on Debian
+tags:
+- Debian
+- GNU+Linux
+- KDE
+---
+
+This is going to be a relatively short and uninteresting post for most, it'll
+just document how to get emoji to work in KDE.
+
+While it will work with most applications out of the box, this doesn't appear to
+work in Qt applications by default, including the notification panel. As I use
+my notifications for messages I get from my work chat, and I dislike seeing the
+squares, I set out to find the solution. I've had to string together a couple
+sources of information to get to the correct setup, and this blog post intends
+to show just the useful bits. So here goes!
+
+You'll need an emoji font (in my case `fonts-noto-color-emoji`), add two
+configuration files for fontconfig, rebuild the fontconfig cache, and most
+likely log out and back into KDE. Installing the emoji font is probably the easy
+bit and won't need any additional explanation I hope. So let's get started on
+the first configuration file, which will enable the Noto emoji font to be used,
+and also force it to be used in favour of other emoji fonts if any application
+was using that specifically. I have it saved as
+`/etc/fonts/conf.d/75-noto-color-emoji.conf`.
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+ <!-- Add generic family. -->
+ <match target="pattern">
+ <test qual="any" name="family"><string>emoji</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+
+ <!-- This adds Noto Color Emoji as a final fallback font for the default font families. -->
+ <match target="pattern">
+ <test name="family"><string>sans</string></test>
+ <edit name="family" mode="append"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test name="family"><string>serif</string></test>
+ <edit name="family" mode="append"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test name="family"><string>sans-serif</string></test>
+ <edit name="family" mode="append"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test name="family"><string>monospace</string></test>
+ <edit name="family" mode="append"><string>Noto Color Emoji</string></edit>
+ </match>
+
+ <!-- Block Symbola from the list of fallback fonts. -->
+ <selectfont>
+ <rejectfont>
+ <pattern>
+ <patelt name="family">
+ <string>Symbola</string>
+ </patelt>
+ </pattern>
+ </rejectfont>
+ </selectfont>
+
+ <!-- Use Noto Color Emoji when other popular fonts are being specifically requested. -->
+ <match target="pattern">
+ <test qual="any" name="family"><string>Apple Color Emoji</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>Segoe UI Emoji</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>Segoe UI Symbol</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>Android Emoji</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>Twitter Color Emoji</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>Twemoji</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>Twemoji Mozilla</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>TwemojiMozilla</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>EmojiTwo</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>Emoji Two</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>EmojiSymbols</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family"><string>Symbola</string></test>
+ <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
+ </match>
+</fontconfig>
+```
+
+The second configuration file, saved as `/etc/fonts/conf.d/local.conf`, simply
+adds the Noto emoji font as a fallback. This enables the use of it when an emoji
+is going to be rendered.
+
+```xml
+<?xml version='1.0'?>
+<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
+<fontconfig>
+ <match target="pattern">
+ <edit name="family" mode="append">
+ <string>Noto Color Emoji</string>
+ </edit>
+ </match>
+</fontconfig>
+```
+
+And after this, a relog of your (graphical) session should be all that is needed
+in order to make it work. You can easily test it with `notify-send`, or trying
+to render some emoji in `konsole`.
diff --git a/content/posts/2023/2023-07-24-new-server-rack-mieshu.md b/content/posts/2023/2023-07-24-new-server-rack-mieshu.md
new file mode 100644
index 0000000..f024784
--- /dev/null
+++ b/content/posts/2023/2023-07-24-new-server-rack-mieshu.md
@@ -0,0 +1,89 @@
+---
+date: 2023-07-23
+title: "My New Server Rack: Mieshu"
+tags:
+- GNU+Linux
+- Gentoo
+- Systemd
+- Garage
+---
+
+After saving up for a long while and thinking about what I want in my new home,
+I have finally taken the leap and gotten myself a server rack for home use. Its
+has a 15U capacity, which should be plenty to get started, but this same brand
+has larger racks too, in case I do want to upgrade it and keep the same style.
+
+That said, for now there's only two 4U units in them, one for (file) storage,
+and one for database purposes. I sadly don't have anything dedicated for
+workloads yet, so for now, both of these servers are intended to also run some
+light workloads. I haven't made my mind up yet on how to solve the workload
+issues. Now that I have a rack, I obviously want something rack-mountable, and
+I probably want it to run a Kubernetes cluster too.
+
+In this regard, I _could_ go for a set of [Raspberry Pi](https://www.raspberrypi.com/)
+units, there's [3U mounts that can hold up to 12 Raspberry Pi machines](https://www.uctronics.com/uctronics-19-inch-3u-rack-mount-for-raspberry-pi-4-with-8-mounting-plates.html),
+which would be a nice amount. However, I am not yet completely sold on full-ARM
+workloads, and I'm not entirely convinced of the power of Raspberry Pi units in
+general. I'd much rather standardize on another brand, [Odroid](https://www.hardkernel.com/),
+as they have more types of units available, and are not limited to just ARM. But
+since they're not the popular kid in class, there's very few off-the-shelf
+rack mounting equipment for it. I'll be thinking about this for just a bit more
+before making a decision.
+
+For now, though, I wanted to talk about the setup of the first server, Mieshu,
+who will be used as a storage server. Mieshu currently runs 8 HDDs, and 2 NVMe
+drives. One of the NVMe drives is used for the rootfs, and the other is used for
+caching in certain applications. The HDDs themselves offer the data storage
+capacity.
+
+The HDDs are currently comprised of four 16TB drives, and four 8TB drives. The
+smaller disks come from my desktop, Edephas, which used to serve as data storage
+until Mieshu took over. All disks are configured into pairs, which themselves
+make mirrors. This means I have four sets of mirror pools, two times 16TB, and
+two times 8TB, for a total of 48TB of storage. I'm currently using about half of
+this, and it should give me plenty of time before needing to increase the size
+again.
+
+I chose to use mirrors since it has a good chance of your data being recoverable
+on disk failure, and it allows me to buy disks per two, rather than in larger
+numbers. This hopefully keeps the cost of expansion within reasonable limits.
+The mirrors themselves are currently [ZFS](https://openzfs.org/wiki/Main_Page)
+pools, but I hope to be able to use [bcachefs](https://bcachefs.org/) very soon
+as well.
+
+Just a bunch of mirrors is rather inconvenient, however, so I'm also leveraging
+[MergerFS](https://github.com/trapexit/mergerfs) to combine all the mirrors into
+a single usable pool. This slightly odd setup was chosen over RAID-0 or RAID-Z*
+to lower the impact of disk failure. Even if two disks in the same mirror were
+the die at the same time, I wouldn't lose _all_ data, just the bits on that
+particular mirror. It would be very annoying, but it wouldn't be disastrous.
+
+Apart from generic mass storage, I also host S3 buckets for personal use. This
+is where I upload CI artifacts to, and [my MissKey instance](https://fedi.tyil.nl/@tyil)
+uses it for storing objects as well. Future services such as [Mimir](https://grafana.com/oss/mimir/)
+will probably leverage S3 for storage as well. This is achieved through
+[Garage](https://garagehq.deuxfleurs.fr/). I've also tried [SeaweedFS](https://seaweedfs.github.io/),
+which is a very neat project on its own, but Garage is just simpler to
+configure, and allows a replicated setup with only two servers, whereas SeaweedFS
+demands an odd number of master servers.
+
+And lastly, Mieshu runs [K3s](https://k3s.io/) for its Kubernetes component. It
+is currently not serving anything yet, as the other server is supposed to become
+the database server, which is needed for most workloads. Once that is up and
+running, Mieshu will start hosting things such as
+[Grafana](https://grafana.com/oss/grafana) and [Loki](https://grafana.com/oss/loki/),
+monitoring stuff basically. Perhaps I'll move [Laminar](https://laminar.ohwg.net/)
+to this server as well, but I'm unsure if I will run that as a Kubernetes service.
+
+The server itself runs on Gentoo, as it still is the most stable experience I
+can get out of any GNU+Linux distribution. I am, however, not using the default
+of OpenRC as the init system and service manager. For the first time, I'm
+running Gentoo with systemd. After several years, it appears to have become
+stable enough to trust with serious workloads. With its increased use, however,
+some things have become simpler by just using systemd. I hope to get a better
+understanding of it, and learn to bend it to my will as needed, by simply using
+it on my own systems.
+
+I hope to have time to work on the other server sooner rather than later, so
+I can finish up the base of my new setup. Be on the lookout for the next post,
+where I'll go into detail on Nouki, the database server.
diff --git a/content/posts/2023/2023-08-05-new-server-rack-nouki.md b/content/posts/2023/2023-08-05-new-server-rack-nouki.md
new file mode 100644
index 0000000..fbbc326
--- /dev/null
+++ b/content/posts/2023/2023-08-05-new-server-rack-nouki.md
@@ -0,0 +1,88 @@
+---
+date: 2023-08-05
+title: "My New Server Rack: Nouki"
+tags:
+- GNU+Linux
+- Gentoo
+- PostgreSQL
+- Prometheus
+- Systemd
+- ZFS
+---
+
+After setting up [mieshu](/post/2023/07/23/my-new-server-rack-mieshu/), nouki is
+the next server to work on in my home rack. Nouki is intended to live as my main
+database server, mainly for PostgreSQL, but perhaps later on in life MySQL if I
+ever want a service that doesn't support superiour databases.
+
+The setup for nouki is much simpler in that regard, the base system is almost
+identical. This server has ZFS with 2 NVMe disks running in a mirror
+configuration. It is also a Gentoo based system, and again with systemd rather
+than openrc. The experience of systemd with mieshu was much less painful than I
+anticipated. It would seem that it has had time to mature, though I still
+dislike how it kills diversity in init/service managers on GNU+Linux.
+
+Both PostgreSQL and ZFS have received some tweaking to run more smoothly. I'm no
+DBA, so if you see anything silly in here, do let me know so I can improve my
+life.
+
+For ZFS, tweaking was rather minimal. I've made a seperate dataset for
+PostgreSQL to use, with `recordsize=8K` as option. For PostgreSQL, I've altered
+a bit more. First and foremost, the `pg_hba.conf` to allow access from machines
+in my tinc-based VPN.
+
+```conf
+host all all 10.57.0.0/16 scram-sha-256
+```
+
+The `postgresql.conf` file received the following treatment, based solely on the
+guidance provided by [PGTune](https://pgtune.leopard.in.ua/).
+
+```conf
+listen_address = 10.57.101.20
+max_connections = 200
+shared_buffers = 8GB
+effective_cache_size = 24GB
+maintenance_work_mem = 2GB
+checkpoint_completion_target = 0.9
+wal_buffers = 16MB
+default_statistics_target = 100
+random_page_cost = 1.1
+effective_io_concurrency = 200
+work_mem = 5242kB
+min_wal_size = 1GB
+max_wal_size = 4GB
+max_worker_processes = 12
+max_parallel_workers_per_gather = 4
+max_parallel_workers = 12
+max_parallel_maintenance_workers = 4
+```
+
+With this, PostgreSQL seems to perform very well on this machine, applications
+using it are noticably faster. Sadly I have no timings from when it all ran on
+my desktop, so I cannot make an exact statement on how much faster everything
+has become.
+
+Additionally, I wanted to start gathering metrics of my machines and services,
+so I can start thinking about dashboards and alerts. I've chosen to use the
+current industry standard of Prometheus for this. Since I consider Prometheus to
+be a database for metrics, it has been deployed on my database server as well.
+
+Prometheus is currently set to scrape metrics from the `node_exporter` and
+`postgresql_exporter`, and seems to work fine. I expect I may need to tweak it
+in the future to configure how long I want metrics to be available, since I've
+seen it use quite a large amount of memory when storing a large amount of
+metrics for a very long time.
+
+To actually see the metrics and have alerts, I currently intend to go with
+Grafana. I already have ntfy running, and it appears relatively simple to mold
+Grafana alerts into ntfy notifications. To do this properly, I will require some
+machines to handle regular workloads. Most likely these will be Intel NUCs, or
+similar machines, as they draw very little power for reasonable performance.
+Raspberry Pi units would be cheaper, but also seem vastly less powerful, and I'd
+need to ensure all my intended workloads can run on ARM which could become a
+nuisance very quickly.
+
+As I already have an Intel NUC to play with, that's what I'll be doing for the
+coming few days to see if this can work for my desires. Perhaps I can try out a
+highly available cluster setup of K3s in the near future!
diff --git a/content/posts/2023/2023-08-29-releasing-raku-modules-with-fez.md b/content/posts/2023/2023-08-29-releasing-raku-modules-with-fez.md
new file mode 100644
index 0000000..edc1914
--- /dev/null
+++ b/content/posts/2023/2023-08-29-releasing-raku-modules-with-fez.md
@@ -0,0 +1,74 @@
+---
+date: 2023-08-29
+title: "Releasing Raku modules with fez"
+tags:
+- Argo
+- Raku
+---
+
+Last week I got a message on Matrix, asking me to update one of my
+[Raku](https://raku.org/) modules,
+[`Config::Parser::TOML`](https://git.tyil.nl/raku/config-parser-toml/). One of
+the dependencies had been updated, and the old one is no longer available
+through the module installer `zef`. Its not that big a change, and there are
+tests available, so its a reasonably small fix on itself.
+
+Recently I've set up [Argo Workflows](https://argoproj.github.io/workflows/) for
+my CI/CD desires, and I found this a good and simple Raku project to try and
+incorporate into a workflow. Since I had some additional quality checks ready to
+use in my workflow, this has resulted in [REUSE](https://reuse.software/)
+compliance for this Raku module, in addition to the regular `prove` tests
+already available in the project. Additionally, the de facto default module
+authoring tool `fez` also brings a few new checks that have been incorporated.
+
+While all that is good, there were some annoyances I encountered while
+configuring this. Notably, I've found `fez` to be a chore to work with when it
+comes to non-interactive use. All CI/CD jobs run in their own Kubernetes pods,
+and _should_ not require any interaction from myself during these runs. I am
+writing this blog post mainly to write down the annoyances I encountered, hoping
+that `fez` can be improved in the future.
+
+Lets start with the first issue I encountered while setting up the workflow:
+`zef install fez` fails by default. `zef` gives the advice to `--exclude` one of
+the dependencies, and going by the issues reported on their Github repository,
+this seems to be accepted workaround. However, I'd argue that this workaround
+should not be needed to begin with. Especially seeing as `fez` works fine and I
+have absolutely no clue what this `z` is or how I can supply it. Either drop
+this dependency, or document its use and upstream so people can package it.
+
+The second issue I encountered was with the `login` functionality of `fez`.
+There seems to be no way to handle this non-interactively. The way around this
+for me has become to use `expect` scripts, but this is obviously not very pretty
+and will break whenever the interactive interface of `fez` changes. A good means
+of non-interactive authentication would be great to have. I've considered to
+just mount `fez`'s config/cache into the containers, but the documentation warns
+that tokens aren't permanent to begin with.
+
+Next up there's the actual `upload` command. I'm running it twice in my
+workflow, once with `--dry-run` and once with `--force`. The first one is done
+as a preliminary quality check to see if there's any obvious issues that ought
+to be fixed beforehand. I noticed on a subsequent run (the one with `--force`)
+that the _dry_ run isn't all that dry. It leaves an `sdist` directory, which in
+turn will get included in the next step. There's a flag to create this `sdist`
+directory, but no flag to do the inverse. My solution is to end this step with
+`rm -fr -- sdist` to clean it up again.
+
+And lastly, when all quality assurance checks have passed, the `fez upload
+--force` command is ran on the working directory. I'd rather not force anything
+here, but the alternative is that another interactive question pops up and the
+job hangs forever. I don't know all the possible prompts `fez` can generate, and
+for this one I didn't even bother to try and look that up. Rather than a
+`--force` to practically say "yes" to everything, I'd prefer an option to say
+"no" to everything, failing the pipeline immediately.
+
+Another pet-peeve of mine is that `fez` seemingly doesn't use exit codes. No
+matter what happens, even something quite important such as `login` with
+incorrect credentials, it _always_ returns `0` as exit code. This should
+obviously be fixed sooner rather than later, as it is quite simple and it is the
+basis for _many_ systems to check the exit code to deduce something is wrong.
+
+Uploads of module updates are currently working, which is good, but I feel like
+a lot of workaround code I had to write should not be necessary. If `fez` can
+fix these issues, it will be much more of a breeze to use, which in turn
+hopefully encourages more automated testing and distributing of Raku modules.
+This can be a great boon for the module ecosystem and overall community.
diff --git a/content/posts/2023/_index.md b/content/posts/2023/_index.md
new file mode 100644
index 0000000..adf7d34
--- /dev/null
+++ b/content/posts/2023/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2023
+---
diff --git a/content/posts/2024/2024-04-02-bashtard-2.1.0.md b/content/posts/2024/2024-04-02-bashtard-2.1.0.md
new file mode 100644
index 0000000..9485dd5
--- /dev/null
+++ b/content/posts/2024/2024-04-02-bashtard-2.1.0.md
@@ -0,0 +1,57 @@
+---
+date: 2024-04-02
+title: Bashtard v2.1.0
+tags:
+- Bash
+- Bashtard
+- FreeBSD
+- GNU+Linux
+---
+Its been about another year since I made a post about Bashtard, its [2.0.0
+release](https://www.tyil.nl/post/2023/05/23/bashtard-v2.0.0/). Today marks the
+[2.1.0 release](https://www.tyil.nl/projects/bashtard/releases/2.1.0), meaning
+I've gone almost a year without breaking backwards compatibility. To me, this is
+a very good sign.
+
+The release today isn't as big as the 2.0.0 release was, mostly because most
+of the functionality I want to have is already present. Some new features were
+added over the year, though. The most important one is _variable references_.
+This allows re-use of a variable's value for another variable. Its quite
+simplistic in how it works, due to the nature of Bashtard being written in Bash
+and trying to keep things rather simple and lightweight. It does however get the
+job done for most use-cases I had for it.
+
+Another feature that was added in this release is the `zap` subcommand. It is a
+convenience command more than anything, simply removing an existing registry
+entry without going through `playbook_del()`. The use case for this is mostly
+for testing new playbooks. I found that while writing a playbook I'd often
+remove the playbook entry from the registry to re-run the `playbook_add()`
+function to see if it works exactly as desired, and I wanted this to be more
+convenient. In theory this new `zap` subcommand is also useful for dealing with
+entries of broken or removed playbooks.
+
+For a future release I'd like to add `import` and `export` subcommands, for
+making it easier to handle external playbooks. The `import` subcommand is
+intended to take an URL and optionally a name to simply add an existing
+repository as a submodule in the `playbooks.d` directory.
+
+The `export` subcommand should take a name as it exists in the `playbooks.d`
+directory and turn it _into_ a git submodule, so it can be pushed to its own
+repository. The intent is that you can just make a regular playbook for use
+within Bashtard, and if you decide "hey, this could actually be useful for
+others in its current state", you can simply export it, and push it to a
+repository for other people to pull from.
+
+Additionally, I would like to remove the `backup` subcommand from Bashtard, as I
+feel it adds a level of bloat and scope-creep which simply should not be there.
+While this would result in a 3.0.0 release of Bashtard, keeping it just for
+backwards compatibility seems a little silly to me.
+
+I'm on the fence for the `ssh` subcommand, as it seems more closely aligned to
+Bashtard being used to manage several systems, and ssh can be very useful to
+check something across your entire network. Considering the recent [SSHd
+vulnerability](https://www.cve.org/CVERecord?id=CVE-2024-3094), it was quite
+easy to run a single command across all my machines and get an overview of which
+machines were affected.
+
+Let's see what the rest of this year brings in Bashtard changes!
diff --git a/content/posts/2024/_index.md b/content/posts/2024/_index.md
new file mode 100644
index 0000000..5321fd3
--- /dev/null
+++ b/content/posts/2024/_index.md
@@ -0,0 +1,3 @@
+---
+title: 2024
+---
diff --git a/content/posts/_index.md b/content/posts/_index.md
new file mode 100644
index 0000000..d6075d8
--- /dev/null
+++ b/content/posts/_index.md
@@ -0,0 +1,16 @@
+---
+title: Blog
+---
+
+Over time, I've written a number of blog posts. Some to voice my opinion, some
+to help people out with a tutorial, or just because I found something fun or
+interesting to talk about. You can find these blog posts on this section of my
+site. If you have any comments, feel free to send an email to
+[`~tyil/public-inbox@lists.sr.ht`](mailto:~tyil/public-inbox@lists.sr.ht), or
+reach out through any other method listed on the home page.
+
+{{< admonition title="note" >}}
+**These articles reflect my opinion, and only mine**. Please refrain from
+accusing other people of holding my opinion for simply being referenced in my
+articles.
+{{< / admonition >}}
diff --git a/content/projects/_index.md b/content/projects/_index.md
new file mode 100644
index 0000000..6907ad3
--- /dev/null
+++ b/content/projects/_index.md
@@ -0,0 +1,7 @@
+---
+title: Projects
+---
+
+This page lists all projects I actively work on, with some information about
+them, releases, any packages, and documentation to get people started on using
+them.
diff --git a/content/projects/bashtard/_index.md b/content/projects/bashtard/_index.md
new file mode 100644
index 0000000..9e31798
--- /dev/null
+++ b/content/projects/bashtard/_index.md
@@ -0,0 +1,17 @@
+---
+title: Bashtard
+repository: https://git.tyil.nl/bashtard
+languages:
+- Bash
+---
+
+Bashtard is a configuration management system built on the idea of simplicity
+for the user. It lets you write reasonably simple Bash scripts to configure
+your systems, while providing just enough abstractions to make it easy to
+work with various base systems.
+
+It is similar in purpose as other configuration management tools, such as
+Ansible and Puppet, however Bashtard tries to keep dependencies to a minimum
+while still providing some abstractions to make the process easier. This
+allows Bashtard to run in more constrained environments, with the abstractions
+allowing it to manage a varied array of systems in a single network.
diff --git a/content/projects/bashtard/releases/1.0.0.md b/content/projects/bashtard/releases/1.0.0.md
new file mode 100644
index 0000000..ef54893
--- /dev/null
+++ b/content/projects/bashtard/releases/1.0.0.md
@@ -0,0 +1,9 @@
+---
+title: Bashtard v1.0.0
+date: 2022-05-06
+type: project-release
+packages:
+ bashtard-1.0.0.tar.gz: https://dist.tyil.nl/packages/bashtard/bashtard-1.0.0.tar.gz
+---
+
+This is the initial release of Bashtard.
diff --git a/content/projects/bashtard/releases/2.0.0.md b/content/projects/bashtard/releases/2.0.0.md
new file mode 100644
index 0000000..29623a7
--- /dev/null
+++ b/content/projects/bashtard/releases/2.0.0.md
@@ -0,0 +1,68 @@
+---
+title: Bashtard v2.0.0
+date: 2023-05-22
+type: project-release
+packages:
+ bashtard-2.0.0.deb: https://dist.tyil.nl/bashtard/bashtard-2.0.0/bashtard-2.0.0.deb
+ bashtard-2.0.0.tar.gz: https://dist.tyil.nl/bashtard/bashtard-2.0.0/bashtard-2.0.0.tar.gz
+---
+
+### Added
+
+- The `var` subcommand is now referenced in `usage()`.
+- A `pkg` subcommand has been added, to allow for direct interaction with the
+ `pkg_*()` utilities provided by Bashtard.
+- `config_subkeys()` and `config_subkeys_for` have been added, to look up
+ subkeys defined in config files. These can help when you want to use a list
+ somewhere in your configuration.
+- A `backup` subcommand has been added. This backup system uses borg, which must
+ be installed, but should be generic enough to be usable by most people out of
+ the box.
+- The `Makefile` has been extended with targets for creating packages for
+ GNU+Linux distributions.
+- The `$BASHTARD_PLATFORM` variable now contains an additional entry, `init`, to
+ allow for handling different init systems on GNU+Linux in a cleaner fashion.
+- A `file_hash` utility function has been added. It currently uses `md5`, but is
+ written in such a fashion that this can easily be updated for the future. Its
+ intent is to encapsulate differences between naming and usage of hashing
+ utilities found on different systems.
+- A `dir_hash` utility function has been added, which will give you a hash based
+ on the file contents of a directory. This function will find files
+ recursively, calculate a hash for each of them, and then calculate a hash
+ based on the total result. The intended goal is to allow running before and
+ after templating some files, to deduce whether something actually changed.
+- A `diff` subcommand has been added to show all non-committed changes. It is a
+ convenience wrapper to avoid having to change directory and run `git diff` to
+ get an overview of all pending changes.
+- A `pull` subcommand has been added to only pull the latest changes into the
+ `$BASHTARD_ETCDIR`, without running `sync` on all the playbooks.
+- A new global variable, `$BASHTARD_PLAYBOOK_VARS` has been added. Currently,
+ its only purpose is to check for "required" variables to be used in the
+ playbook. Before an `add` or `sync`, any variables declared to be `required`
+ in the `$BASHTARD_PLAYBOOK_VARS` array will be checked to be non-empty. If any
+ are empty, an error will be thrown and the playbook will not be ran.
+- A new directory has been added, `data.d`, for data that should be shared
+ between playbook runs. This new directory is intended to create a clearer
+ seperation between a playbook and a user's specific data used by the playbook,
+ which in turn should make re-using playbooks easier.
+- A convenience function has been introduced, `playbook_path()`, which can give
+ you the absolute path to the playbook's base or data directory.
+- A `top` subcommand has been added to give some generic information of all
+ nodes known to Bashtard. It uses information from the `sysinfo` subcommand,
+ which it will pull in through an `ssh` invocation.
+
+### Changed
+
+- The `ssh` subcommand's configuration has been nested under `bashtard`, e.g.
+ `ssh.host` is now `bashtard.ssh.host`. It should also be correctly using this
+ value for establishing the SSH connection.
+- `svc_enable()` now checks for the `rc.d` file to exist before running `grep`
+ on it.
+- `pkg_*()` functions no longer _require_ a `pkg.*` value to be defined. If one
+ is not set explicitly, a warning will be generated, but the original name
+ passed to the `pkg_*()` function will be used by the host's package manager.
+- `datetime()` now always passes `-u` on to `date`.
+- All manpages now include a `NAME` section.
+- The `sync` subcomman will now `stash` any changes before it attempts to
+ `pull`. Afterwards, `stash pop` will be ran to apply the last `stash`ed
+ changes again.
diff --git a/content/projects/bashtard/releases/2.0.1.md b/content/projects/bashtard/releases/2.0.1.md
new file mode 100644
index 0000000..e8bf49c
--- /dev/null
+++ b/content/projects/bashtard/releases/2.0.1.md
@@ -0,0 +1,19 @@
+---
+title: Bashtard v2.0.1
+date: 2023-09-25
+type: project-release
+packages:
+ bashtard-2.0.1.deb: https://dist.tyil.nl/bashtard/bashtard-2.0.1/bashtard-2.0.1.deb
+ bashtard-2.0.1.tar.gz: https://dist.tyil.nl/bashtard/bashtard-2.0.1/bashtard-2.0.1.tar.gz
+---
+
+### Added
+
+- A new `make` target has been added to build a .tar.gz distributable.
+
+### Changed
+
+- The `svc_` utils should now check which init service you're using when using a
+ linux system. The supported options are still only openrc and systemd.
+- The `pull` subcommand should now properly return with exit-code 0 if no
+ problem were encountered.
diff --git a/content/projects/bashtard/releases/2.0.2.md b/content/projects/bashtard/releases/2.0.2.md
new file mode 100644
index 0000000..5acaaa9
--- /dev/null
+++ b/content/projects/bashtard/releases/2.0.2.md
@@ -0,0 +1,13 @@
+---
+title: Bashtard v2.0.2
+date: 2024-02-28
+type: project-release
+packages:
+ bashtard-2.0.2.deb: https://dist.tyil.nl/bashtard/bashtard-2.0.2/bashtard-2.0.2.deb
+ bashtard-2.0.2.tar.gz: https://dist.tyil.nl/bashtard/bashtard-2.0.2/bashtard-2.0.2.tar.gz
+---
+
+### Fixed
+
+- Configuration values with `=` in their value part should now work properly
+ with `file_template`. Keys with `=` in them are still *not supported*.
diff --git a/content/projects/bashtard/releases/2.1.0.md b/content/projects/bashtard/releases/2.1.0.md
new file mode 100644
index 0000000..24caa53
--- /dev/null
+++ b/content/projects/bashtard/releases/2.1.0.md
@@ -0,0 +1,29 @@
+---
+title: Bashtard v2.1.0
+date: 2024-04-02
+type: project-release
+packages:
+ bashtard-2.1.0.deb: https://dist.tyil.nl/bashtard/bashtard-2.1.0/bashtard-2.1.0.deb
+ bashtard-2.1.0.tar.gz: https://dist.tyil.nl/bashtard/bashtard-2.1.0/bashtard-2.1.0.tar.gz
+---
+
+### Added
+
+- Configuration variables can be assigned values of other variables with the
+ `&=` assignment. This allows a single value to be re-used dynamically, rather
+ than having to explicitly set the same value several times.
+- A `zap` command has been added to remove a playbook from the registry without
+ running the playbook's `playbook_del()` function. This is intended to easily
+ remove registry entries when a playbook itself has been deleted or is
+ otherwise broken in a way that the regular `del` subcommand cannot fix.
+
+### Changed
+
+- The `description.txt` is now allowed to be used without the `.txt` suffix.
+ Usage with the `.txt` suffix continues to be supported as well.
+
+### Fixed
+
+- Passing an empty string as default value to `config` should now properly
+ return an empty string without a warning about the configuration key not
+ existing.
diff --git a/content/projects/bashtard/releases/_index.md b/content/projects/bashtard/releases/_index.md
new file mode 100644
index 0000000..c98ddda
--- /dev/null
+++ b/content/projects/bashtard/releases/_index.md
@@ -0,0 +1,4 @@
+---
+title: Bashtard
+type: project-release
+---
diff --git a/content/recipes/_index.md b/content/recipes/_index.md
new file mode 100644
index 0000000..337e63b
--- /dev/null
+++ b/content/recipes/_index.md
@@ -0,0 +1,9 @@
+---
+title: Cookbook
+---
+
+People have often asked me to share recipes for various meals and snacks I've
+served over time, so I've started writing down my recipes. This section of my
+blog covers these recipes in my own personal cookbook. If you want to stay up to
+date with the latest additions, subscribe to the [RSS
+feed](/recipes/index.xml).
diff --git a/content/recipes/basics/bechamel.md b/content/recipes/basics/bechamel.md
new file mode 100644
index 0000000..1839a6e
--- /dev/null
+++ b/content/recipes/basics/bechamel.md
@@ -0,0 +1,34 @@
+---
+title: Bechamel
+date: 2022-04-18
+preptime: 0
+cooktime: 10
+serves: 1
+tags:
+- basics
+
+ingredients:
+- label: Butter
+ amount: 50
+ unit: grams
+- label: Flour
+ amount: 60
+ unit: grams
+- label: Milk
+ amount: .25
+ unit: liter
+
+stages:
+- label: Cooking
+ steps:
+ - Put the pot on low heat.
+ - Add the butter to the pot and let it melt completely.
+ - Once completely melted, immediately add the flour.
+ - Keep on low heat, and continuously stir the mixture to avoid burning.
+ - After 3 - 5 minutes, the mixture will smell slightly nutty, indicating the
+ flour is cooked.
+ - While stirring, slowly add the milk to the mixture.
+ - Let this cook for 3 - 5 minutes, until you reach your desired viscosity.
+---
+
+A thick, creamy sauce, usually as a base for another thick and savory sauce.
diff --git a/content/recipes/condiments/applesauce.md b/content/recipes/condiments/applesauce.md
new file mode 100644
index 0000000..2b0603e
--- /dev/null
+++ b/content/recipes/condiments/applesauce.md
@@ -0,0 +1,38 @@
+---
+title: Applesauce
+date: 2022-04-18
+tags:
+- condiments
+- sweet
+preptime: 75
+cooktime: 10
+serves: 1
+
+ingredients:
+- label: Apple
+ amount: 5
+- label: Water
+ unit: liter
+ amount: 1
+- label: Cinnamon
+
+stages:
+- label: Preparation
+ steps:
+ - Peel the apples.
+ - Cut the apples into small chunks.
+- label: Cooking
+ steps:
+ - Put the apples in the pot.
+ - Add water to the pot, just enough to cover about half of the apple.
+ - Put the pot on the stove, and turn it on to high heat.
+ - When the water starts bubbling, lower the heat to about a third, and cover
+ the pot with a lid kept slightly ajar.
+ - Let this cook for about 10 to 15 minutes.
+ - Once cooked, drain the water from the pot.
+ - Mash the apples to your preferred thickness.
+ - Add cinnamon to taste.
+ - Let cool completely in the fridge.
+---
+
+A sweet, thick sauce made of apple.
diff --git a/content/recipes/condiments/mayonnaise.md b/content/recipes/condiments/mayonnaise.md
new file mode 100644
index 0000000..ec17290
--- /dev/null
+++ b/content/recipes/condiments/mayonnaise.md
@@ -0,0 +1,40 @@
+---
+title: Mayonnaise
+date: 2022-11-20
+preptime: 5
+cooktime: 10
+serves: 5
+tags:
+- condiment
+- vegetarian
+
+ingredients:
+- label: Egg
+ amount: 3
+- label: Lemon Juice
+ amount: 10
+ unit: grams
+- label: Mustard
+ amount: 25
+ unit: grams
+- label: Olive Oil (Mild)
+ amount: 200
+ unit: grams
+
+stages:
+- label: Preparing
+ steps:
+ - Seperate the egg whites from the yolks
+ - Put the yolks into a tall container for easy mixing with a stick blender
+ - Add the mustard to the container
+- label: Mixing
+ steps:
+ - Start mixing the ingredients in the tall container
+ - Slowly add in the oil, ensuring it all gets blended into a thick mass
+ - Continuously add in the oil until all is used
+ - Add in the lemon juice
+ - Mix for another minute or so to ensure the juice is incorporated properly
+---
+
+A simple sauce to go well with everything, though most popular with french
+fries.
diff --git a/content/recipes/condiments/salsa.md b/content/recipes/condiments/salsa.md
new file mode 100644
index 0000000..01b81e2
--- /dev/null
+++ b/content/recipes/condiments/salsa.md
@@ -0,0 +1,59 @@
+---
+title: Sweet and Spicy Salsa
+date: 2022-10-02
+draft: true
+tags:
+- snacks
+- sweet
+- spicy
+preptime: 15
+cooktime: 0
+serves: 4
+
+ingredients:
+- label: Bell Pepper
+ amount: 50
+ unit: grams
+- label: Black Pepper
+- label: Garlic
+ amount: 2
+ unit: cloves
+- label: Honey
+ amount: 1
+ unit: tablespoon
+- label: Jalapeno
+ amount: 25
+ unit: grams
+- label: Ketjap Manis
+ amount: 1
+ unit: tablespoon
+- label: Red Onion
+ amount: 50
+ unit: grams
+- label: Salt
+- label: Spring Onion
+ amount: 25
+ unit: grams
+- label: Tomato
+ amount: 100
+ unit: grams
+- label: Worcestershire Sauce
+ amount: 1
+ unit: tablespoon
+
+stages:
+- label: Preparations
+ steps:
+ - Chop all choppable ingredients into small bits.
+ - Combine all ingredients in a bowl.
+ - Mix around until it combines into a salsa.
+---
+
+A sweet and spicy salsa, great for parties.
+
+<!--more-->
+
+It is inspired by the cooking video from You Suck At Cooking, which teaches [the
+way of rgogsh](https://youtube.alt.tyil.nl/watch?v=HCNwSe3t8ek). This recipe has
+been made over time to create my favourite salsa, but you can easily swap a few
+ingredients around to get something that works for all sorts of parties.
diff --git a/content/recipes/condiments/sauce-mushroom.md b/content/recipes/condiments/sauce-mushroom.md
new file mode 100644
index 0000000..0865faf
--- /dev/null
+++ b/content/recipes/condiments/sauce-mushroom.md
@@ -0,0 +1,65 @@
+---
+title: Mushroom Sauce
+date: 2022-09-30
+tags:
+- condiments
+- savory
+preptime: 5
+cooktime: 25
+serves: 1
+
+ingredients:
+- label: Butter
+ amount: 50
+ unit: gram
+- label: Cream
+ amount: 150
+ unit: gram
+- label: Garlic
+ amount: 2
+ unit: clove
+- label: Mushrooms
+ amount: 100
+ unit: gram
+- label: Mustard
+ amount: 1
+ unit: teaspoon
+- label: Onion
+ amount: 1
+- label: Thyme
+ amount: 1
+ unit: teaspoon
+- label: White Wine
+ amount: 0.05
+ unit: liter
+- label: Worcestershire Sauce
+ amount: 0.02
+ unit: liter
+- label: Pepper
+- label: Salt
+
+stages:
+- label: Preparation
+ steps:
+ - Clean and cut the mushrooms.
+ - Finely dice the onions.
+ - Finely dice the garlic.
+ - Chop the thyme.
+- label: Cooking
+ steps:
+ - Melt the butter in a pan with a little bit of oil to prevent the butter from
+ burning.
+ - Add the onion and garlic and fry for about 1 minute.
+ - Add the mushrooms and fry until cooked, about 3 to 4 minutes.
+ - Add a pinch of salt
+ - Reduce the heat.
+ - Add the white wine to deglaze the pan.
+ - Add the cream to the pan.
+ - Add the mustard to the pan.
+ - Add the worcestershire sauce to the pan.
+ - Add the thyme to the pan.
+ - Add the pepper to the pan.
+ - Stir everything together, and let simmer for 10 to 15 minutes to thicken up.
+---
+
+A savory sauce to be served warm with your dish. Works very well for steaks.
diff --git a/content/recipes/condiments/sriracha.md b/content/recipes/condiments/sriracha.md
new file mode 100644
index 0000000..4db9370
--- /dev/null
+++ b/content/recipes/condiments/sriracha.md
@@ -0,0 +1,29 @@
+---
+title: Sriracha Sauce
+date: 2022-04-18
+tags:
+- condiments
+- spicy
+preptime: 10
+cooktime: 432000
+serves: 1
+
+ingredients:
+- label: Peppers
+- label: Garlic
+- label: Sugar
+- label: Salt
+
+stages:
+- label: Preperation
+ steps:
+ - Cut the peppers in chunks that will easily blend
+ - Weigh all the ingredients without the salt
+ - Take 3% of the total weight as salt, and add it to the rest of the ingredients
+ - Blend it all together until smooth
+- label: Fermentation
+ steps:
+ - Let ferment for 5 - 30 days
+---
+
+A very spicy variant of the world's most popular hot sauce.
diff --git a/content/recipes/dishes-hot/meatball-jordanese.md b/content/recipes/dishes-hot/meatball-jordanese.md
new file mode 100644
index 0000000..f609e2e
--- /dev/null
+++ b/content/recipes/dishes-hot/meatball-jordanese.md
@@ -0,0 +1,66 @@
+---
+title: Jordanese Meatball
+date: 2022-04-18
+preptime: 20
+cooktime: 270
+serves: 1
+tags:
+- meal
+- hot
+
+ingredients:
+- label: Minced meat
+ ratio: 1
+ amount: 150
+ unit: grams
+- label: Egg
+ ratio: 0.05
+ amount: 7.5
+ unit: grams
+- label: Garlic
+- label: Onion
+- label: Salt
+ ratio: 0.012
+ amount: 18
+ unit: grams
+- label: Black Pepper
+ ratio: 0.004
+ amount: 1
+ unit: grams
+- label: Nutmeg
+ ratio: 0.002
+ amount: 0.5
+ unit: grams
+- label: Panko
+ ratio: 0.08
+ amount: 12
+ unit: grams
+- label: Cayenne Pepper
+ ratio: 0.002
+ amount: 0.5
+ unit: grams
+
+stages:
+- label: Pre-cook
+ steps:
+ - Sweat the garlic and onion
+ - Set the garlic and onion aside to cool off
+- label: Shaping
+ steps:
+ - Toss all the other ingredients into a mixing bowl
+ - Mix together
+ - Add the cool onion and garlic
+ - Mix together
+ - Form the meat into balls
+ - Cover the meatballs in panko
+- label: Cooking
+ steps:
+ - Fry the meatballs to ensure a crust forms outside of it (10 min)
+ - Fill a dutch oven with enough (meat) stock to almost fully submerge the
+ meatballs
+ - Let the stock thicken up slightly
+ - Put in the meatballs, making sure they are submerged.
+ - Cook the meatballs slowly until completely cooked through.
+---
+
+A slowly stewed meatball.
diff --git a/content/recipes/dishes-hot/pancakes.md b/content/recipes/dishes-hot/pancakes.md
new file mode 100644
index 0000000..1781092
--- /dev/null
+++ b/content/recipes/dishes-hot/pancakes.md
@@ -0,0 +1,46 @@
+---
+draft: true
+title: Pancakes
+date: 2022-04-18
+preptime: 5
+cooktime: 15
+serves: 3
+tags:
+- meal
+- hot
+
+ingredients:
+- label: Egg
+ amount: 1
+- label: Flour
+ amount: 150
+ unit: grams
+- label: Milk
+ amount: 250
+ unit: milliliters
+- label: Bacon
+- label: Cinnamon
+
+stages:
+- label: Batter
+ steps:
+ - Put the eggs into the mixing bowl.
+ - Use the mixer to stir them into a homogenous liquid, for about 30 to 45 seconds.
+ - Add the milk, and mix together until homogenous again, about 5 to 10 seconds.
+ - Add the flour, and mix into a smooth batter, about 1 to 3 minutes.
+- label: Cooking
+ steps:
+ - Get your pan as hot as you can.
+ - Add a little butter (or oil) to the pan, and ensure it covers the entire pan slightly.
+ - Put some strips of bacon in the pan.
+ - Immediately after, add 1 scoop of pancake batter. Start pouring over the
+ bacon, then swirl around the pan to spread the batter around the surface of
+ the pan.
+ - Let the pancake cook until the top side is solid.
+ - Flip the pancake.
+ - Let cook for another 30 to 60 seconds.
+ - Rinse and repeat until you're out of pancake batter.
+---
+
+Thin, Dutch pancakes with bacon. To be eaten with the gift of the Dutch Gods,
+known as [Stroop](https://nl.wikipedia.org/wiki/Stroop).
diff --git a/content/recipes/dishes-hot/soup-mushroom-cream.md b/content/recipes/dishes-hot/soup-mushroom-cream.md
new file mode 100644
index 0000000..5a0d43e
--- /dev/null
+++ b/content/recipes/dishes-hot/soup-mushroom-cream.md
@@ -0,0 +1,68 @@
+---
+draft: true
+title: Cream of Mushroom Soup
+date: 2022-10-08
+preptime: 20
+cooktime: 60
+serves: 5
+tags:
+- hot
+- meal
+- soup
+- vegetarian
+
+ingredients:
+- label: Butter
+ amount: 25
+ unit: grams
+- label: Cream (40%)
+ amount: 750
+ unit: milliliter
+- label: Mushroom
+ amount: 500
+ unit: grams
+- label: Parsley
+- label: Parmesan
+ amount: 50
+ unit: grams
+- label: Vegetable Stock
+ amount: 100
+ unit: milliliter
+- label: Onion
+ amount: 200
+ unit: grams
+- label: Shallot
+ amount: 50
+ unit: grams
+
+stages:
+- label: Preparation
+ steps:
+ - Cut the onions in half circles.
+ - Cut the shallots into half circles.
+ - Cut the mushrooms into quarter slices.
+ - Grate the parmesan.
+ - Finely chop the parsley.
+- label: Caramelizing the Onion
+ steps:
+ - Get your soup pot, and add the butter to it.
+ - Set your stove to medium-high.
+ - Let the butter melt completely.
+ - Add the onions to the pot.
+ - Add the shallots to the pot.
+ - Cook until the onions become soft, about 5 minutes.
+ - Turn your stove to low-medium heat.
+ - Continue cooking while stirring occasionally, until the onions become brown.
+- label: Soup
+ steps:
+ - Deglaze the pot with the vegetable stock.
+ - Add the mushrooms.
+ - Cook until the mushrooms turn soft, about 10 minutes.
+ - Add the cream.
+ - Add the parmesan.
+ - Add the parsley.
+ - Stir everything together, and let cook for about 5 more minutes.
+ - Add salt and pepper to taste.
+---
+
+My own take of a cream-based mushroom soup.
diff --git a/content/recipes/dishes-hot/soup-pea-halal.md b/content/recipes/dishes-hot/soup-pea-halal.md
new file mode 100644
index 0000000..231b984
--- /dev/null
+++ b/content/recipes/dishes-hot/soup-pea-halal.md
@@ -0,0 +1,86 @@
+---
+title: Halal Pea Soup
+date: 2022-10-16
+preptime: 30
+cooktime: 120
+serves: 8
+tags:
+- hot
+- meal
+- soup
+- halal
+
+ingredients:
+- label: Vegetable Broth
+ amount: 3
+ unit: liter
+- label: Split peas (dried)
+ amount: 500
+ unit: grams
+- label: Beef ribs, including bone
+ amount: 400
+ unit: grams
+- label: Lamb strips, with fat
+ amount: 300
+ unit: grams
+- label: Smoked Sausage (chicken)
+ amount: 250
+ unit: grams
+- label: Carrot
+ amount: 350
+ unit: grams
+- label: Onion
+ amount: 200
+ unit: grams
+- label: Leek
+ amount: 150
+ unit: grams
+- label: Celery
+ amount: 100
+ unit: grams
+- label: Potato
+ amount: 250
+ unit: grams
+- label: Celeriac
+ amount: 300
+ unit: grams
+- label: Salt
+- label: Black Pepper
+- label: Parsley
+
+stages:
+- label: Preparation
+ steps:
+ - Cut the smoked sausage into slices.
+ - Cut all the vegetables into small bits.
+ - Caramelize the onion.
+- label: Base
+ steps:
+ - Pour the vegetable stock in the pot.
+ - Add the split peas.
+- label: Meats
+ steps:
+ - Add the beef ribs.
+ - Add the lamb strips.
+ - Bring the entire mixture to a soft boil.
+ - Let boil for 45 minutes, stirring every 5 minutes. Skim off any scum that
+ floats to the top.
+ - Remove the meats from the pot.
+ - Debone the beef ribs.
+ - Cut the lamb strips into smaller bits.
+ - Put the meats back into the pot.
+- label: Vegetables
+ steps:
+ - Add the all the vegetables.
+ - Add the parsley.
+ - Let boil for at least 1 hour, stirring every 5 to 10 minutes. The peas need
+ to be dissolved, and the soup should be a little thick.
+- label: Finishing Touches
+ steps:
+ - Add salt and pepper to taste.
+- label: Serving
+ steps:
+ - Let sit overnight, and serve the next day for optimal enjoyment.
+---
+
+A halal version of a famous Dutch winter meal, pea soup.
diff --git a/content/recipes/dishes-hot/stew-dutch.md b/content/recipes/dishes-hot/stew-dutch.md
new file mode 100644
index 0000000..9806492
--- /dev/null
+++ b/content/recipes/dishes-hot/stew-dutch.md
@@ -0,0 +1,97 @@
+---
+title: Dutch Stew
+draft: true
+date: 2022-05-22
+preptime: 30
+cooktime: 450
+serves: 4
+tags:
+- Dutch
+- beef
+- hot
+- meal
+- meat
+
+ingredients:
+- label: Beef
+ amount: 500
+ unit: grams
+- label: Sweet onion
+ amount: 2 (large)
+- label: Garlic
+ amount: 3
+ unit: teaspoons
+- label: Leek
+ amount: 1
+- label: Beans
+ amount: 200
+ unit: grams
+- label: Carrot
+ amount: 300
+ unit: grams
+- label: Chick peas
+ amount: 200
+ unit: grams
+- label: Mushrooms
+ amount: 200
+ unit: grams
+- label: Oudewijvenkoek
+ amount: 3
+ unit: slices
+ links:
+ - https://nl.wikipedia.org/wiki/Oudewijvenkoek
+- label: Beef stock
+ amount: 750
+ unit: milliliters
+- label: Dark beer
+ amount: 330
+ unit: milliliters
+- label: Appelstroop
+ amount: 2
+ unit: tablespoons
+ links:
+ - https://nl.wikipedia.org/wiki/Appelstroop
+- label: Mustard
+ amount: 3
+ unit: teaspoons
+- label: Bay leaf
+ amount: 4
+- label: Pepper
+- label: Salt
+- label: Smoked paprika
+- label: Thyme
+
+stages:
+- label: Prep
+ steps:
+ - Cut the beef into bite-sized chunks
+ - Cut all the vegetables into chunks, about 1cm in diameter where applicable
+ - Slice off 3 slices of the oudewijvenkoek, about 1cm thick
+ - Spread the mustard unto one side of the oudewijvenkoek slices
+- label: Searing
+ steps:
+ - Sear the beef on all sides
+ - Remove the beef from the pot
+- label: Stewing
+ steps:
+ - Saute the onions in the pot
+ - Add in the garlic, cook for about half a minute
+ - Add the leek to the pot, and cook for a minute
+ - Add the carrot to the pot
+ - Add the beer and beef stock to the pot
+ - Add the bay leaves to the pot
+ - Add the appelstroop to the pot
+ - Stir everything together
+ - Add the mustard-laced oudewijvenkoek, with the mustard facing down in the
+ pot
+ - Let this stew for about 6 hours, occasionally checking in to make sure its
+ simmering slowly. If too much liquid evaporates, you can add more water or
+ beef stock, the solids should be completely submerged
+ - Add the spices (pepper, salt, smoked paprika, thyme) to reach your desired
+ flavour
+ - Add the potatoes, chickpeas, and beans to the pot
+ - Let it stew for another 90 - 120 minutes
+---
+
+A hearthy and veggie-heavy stew, best served when the weather outside is cold
+and wet.
diff --git a/content/recipes/dishes-side/salad-stewed-beaf.md b/content/recipes/dishes-side/salad-stewed-beaf.md
new file mode 100644
index 0000000..c7e6d15
--- /dev/null
+++ b/content/recipes/dishes-side/salad-stewed-beaf.md
@@ -0,0 +1,133 @@
+---
+title: Stewed Beef Salad
+date: 2022-11-20
+preptime: 30
+cooktime: 300
+serves: 14
+tags:
+- Dutch
+- cold
+- meat
+- beef
+- salad
+
+ingredients:
+- label: Stewed Beef
+ amount: 500
+ unit: grams
+- label: Mayonnaise
+ amount: 400
+ unit: grams
+ links:
+ - /recipes/condiments/mayonnaise/
+- label: Pickle
+ amount: 150
+ unit: grams
+- label: Potato
+ amount: 250
+ unit: grams
+- label: Carrot
+ amount: 150
+ unit: grams
+- label: Red Onion
+ amount: 150
+ unit: grams
+- label: Spring Onion
+ amount: 150
+ unit: grams
+- label: Capers
+ amount: 150
+ unit: grams
+- label: Egg
+ amount: 7
+- label: Paprika
+- label: Salt
+- label: Pepper
+- label: Garlic Powder
+
+stages:
+- label: Stewing
+ notes: |
+ This is a very simple means of stewing beef. You can adapt this to your
+ preferred recipe for stewed beef and use it all the same. Since this is the
+ longest process, you can perform all other steps in the meantime.
+ steps:
+ - Cut the beef into bite-sized cubes
+ - Sear the cubes of beef on all sides
+ - Put the seared beef in a pot
+ - Fill the pot with stock until all the beef is covered
+ - Add bay leaves to the pot
+ - Add apple syrup to the pot
+ - Add paprika to the pot
+ - Let the beef stew for about 4 hours
+- label: Chopping
+ notes: |
+ All the ingredients should be chopped to around the same size, around 2
+ millimeters big. The finer you chop, the smoother the eventual salad will
+ be.
+ steps:
+ - Chop the pickle
+ - Chop the red onion
+ - Chop the spring onion
+ - Chop the carrot
+ - Chop the potatoes
+- label: Cooking
+ notes: |
+ The cooking process removes the raw taste, and makes the ingredients
+ slightly softer. Depending on how finely you chopped the ingredients, this
+ process only has to take 1 or 2 minutes per ingredient.
+ steps:
+ - Bring a pot of water to a boil
+ - Put in the chopped carrot
+ - Boil until _just_ ready
+ - Remove the carrot from the pot
+ - Rinse the carrot in cold water until the carrot is completely cooled off
+ - Repeat the cooking steps for the potatoes
+ - Boil the eggs for about 9 minutes
+- label: Drying
+ notes: |
+ All the ingredients should be reasonably dry before mixing it all together,
+ or the salad will get watery and soggy. The method I use for drying all
+ these ingredients is to put them between sheets of paper towel, and press
+ down on it to expunge most of the moisture, then remove the paper towels.
+ steps:
+ - Dry the pickles
+ - Dry the red onion
+ - Dry the spring onion
+ - Dry the carrots
+ - Dry the potatoes
+ - Dry the capers
+- label: Combining
+ steps:
+ - Shred the stewed beef
+ - Grab a big bowl
+ - Add the pickles
+ - Add the red onion
+ - Add the spring onion
+ - Add the carrots
+ - Add the potatoes
+ - Add the capers
+ - Add the shredded beef
+ - Add the mayonnaise
+ - Mix together until combined into a cohesive salad
+ - Add salt, pepper, paprika, and garlic powder to taste
+- label: Serving
+ notes: |
+ You can obviously serve it in any way you desire, but this is how I
+ traditionally encountered it.
+ steps:
+ - Cut the boiled eggs in half
+ - Place the salad on a plate
+ - Add a boiled egg on top, cut side up
+ - Garnish with leftover pickle and spring onion
+---
+
+A small, hearty salad. Served cold, usually as a side-dish, but also works great
+as a little snack.
+
+<!--more-->
+
+If you use home-made mayonnaise, you can cook the egg whites in a scrambled
+fasion, and add it to the salad as well. This won't affect the flavour too much,
+but will make it a more filling snack, and you won't have to make meringue
+_again_.
diff --git a/content/recipes/dishes-side/stewed-pears.md b/content/recipes/dishes-side/stewed-pears.md
new file mode 100644
index 0000000..9312feb
--- /dev/null
+++ b/content/recipes/dishes-side/stewed-pears.md
@@ -0,0 +1,50 @@
+---
+title: Stewed Pears
+date: 2022-11-20
+preptime: 10
+cooktime: 180
+serves: 2
+tags:
+- cold
+- fruit
+- sweet
+- vegetarian
+
+ingredients:
+- label: Stewing Pears
+ amount: 400
+ unit: grams
+- label: Cinnamon
+ amount: 4
+ unit: grams
+- label: Light Caster Sugar
+ amount: 16
+ unit: grams
+- label: Strawberry Lemonade Syrup
+ amount: 20
+ unit: grams
+- label: Water
+
+stages:
+- label: Preparation
+ steps:
+ - Peel the pears, and remove the cores.
+ - Cut the pears into quarters.
+- label: Stewing
+ steps:
+ - Put the pears in a pot.
+ - Fill the pot with water until it covers all the pears.
+ - Add the cinnamon.
+ - Add the sugar.
+ - Add the syrup.
+ - Stir until everything is combined.
+ - Let the pears stew until they are soft and have changed their color to a
+ bright pink.
+---
+
+A sweet dish, commonly served with gamey-meat or stewed meat.
+
+<!--more-->
+
+Originally made by my grandmother, this recipe is my attempt to get as close as
+possible to this little treat.
diff --git a/content/recipes/dishes-side/waffles.md b/content/recipes/dishes-side/waffles.md
new file mode 100644
index 0000000..4a5165d
--- /dev/null
+++ b/content/recipes/dishes-side/waffles.md
@@ -0,0 +1,56 @@
+---
+title: Waffles
+date: 2024-04-15
+preptime: 10
+cooktime: 5
+serves: 2
+tags:
+- warm
+- sweet
+- vegetarian
+
+ingredients:
+- label: Flour
+ amount: 100
+ unit: grams
+- label: Granulated Sugar
+ amount: 30
+ unit: grams
+- label: Baking powder
+ amount: 10
+ unit: grams
+- label: Salt
+- label: Milk
+ amount: 100
+ unit: milliliters
+- label: Egg
+ amount: 50
+ unit: grams
+- label: Vanilla Extract
+ amount: 1
+ unit: teaspoon
+- label: Butter
+ amount: 25
+ unit: grams
+
+stages:
+- label: Preparation
+ steps:
+ - Put the butter in the microwave until it is completely melted
+ - Mix all ingredients together in a mixing bowl until the batter is smooth
+- label: Baking
+ steps:
+ - Ensure your waffle iron is on optimal temperature
+ - Apply the appropriate amount of batter to the waffle iron
+ - Let bake until lightbrown
+---
+
+Sweet and fluffy waffles. Great as a snack or as a side-dish to a larger meal.
+
+<!--more-->
+
+These waffles can be served with ice cream and/or fruit to create a simple but
+delicious snack or dessert. The instructions for the baking itself are rather
+simplistic, but it appears that waffle irons differ wildly in size and settings
+even in my own country, let alone in other countries. For this reason, you may
+need to experiment a little with your waffle iron of choice.
diff --git a/content/recipes/snacks/buttercake.md b/content/recipes/snacks/buttercake.md
new file mode 100644
index 0000000..0441fab
--- /dev/null
+++ b/content/recipes/snacks/buttercake.md
@@ -0,0 +1,53 @@
+---
+title: Buttercake
+date: 2022-04-18
+tags:
+- snacks
+- rich
+- sweet
+preptime: 15
+cooktime: 30
+serves: 8
+
+ingredients:
+- label: Egg
+ amount: 1
+- label: Butter
+ amount: 200
+ unit: grams
+- label: Flour
+ amount: 250
+ unit: grams
+- label: Granulated Sugar
+ amount: 200
+ unit: grams
+- label: Vanilla Sugar
+ amount: 8
+ unit: grams
+
+stages:
+- label: Preparations
+ steps:
+ - Ensure the butter is on room temperature
+ - Heat up the oven to 180℃
+- label: Batter
+ steps:
+ - Whip the butter until its nice and soft
+ - Add in the sugars, and mix until combined
+ - Add in an egg, and mix until combined
+ - Sift in the flour, and mix until combined
+- label: Shaping
+ steps:
+ - Butter your cake tin
+ - Put the cake batter into the cake tin
+ - Smooth out the cake batter, using a wet spoon
+ - Using a fork, carve a diamond pattern on the cake batter
+ - Put your 2nd egg in a small cup, and whisk into a single cohesive substance
+ - Lightly coat the cake with egg
+- label: Baking
+ steps:
+ - Bake in the oven for 25-30 minutes
+ - Let it cool to room temperature, preferably leaving it overnight until serving
+---
+
+A rich snack from the glorious Netherlands.
diff --git a/content/recipes/snacks/cheesecake-basque-burned.md b/content/recipes/snacks/cheesecake-basque-burned.md
new file mode 100644
index 0000000..e59b9b2
--- /dev/null
+++ b/content/recipes/snacks/cheesecake-basque-burned.md
@@ -0,0 +1,65 @@
+---
+title: Basque-burned Cheesecake
+date: 2022-04-18
+tags:
+- snacks
+- sweet
+preptime: 75
+cooktime: 10
+serves: 1
+
+ingredients:
+- label: Cream cheese
+ amount: 900
+ unit: grams
+- label: Egg
+ amount: 500
+ unit: grams
+- label: Flour
+ amount: 50
+ unit: grams
+- label: Granulated sugar
+ amount: 300
+ unit: grams
+- label: Heavy cream (35% fat)
+ amount: 500
+ unit: grams
+- label: Creme Fraiche
+ amount: 125
+ unit: grams
+- label: Salt
+ amount: 1
+ unit: teaspoon
+- label: Vanilla extract
+ amount: 1
+ unit: tablespoon
+
+stages:
+- label: Preparation
+ steps:
+ - Ensure all the ingredients are at room temperature.
+ - Turn on the oven to 477K
+- label: Batter
+ steps:
+ - Put the cream cheese into the mixing bowl.
+ - Put the sugar into the mixing bowl.
+ - On a low speed, mix the cream cheese and sugar together into a single, soft mixture.
+ - Add in one egg, and mix until combined, repeat until all eggs have been mixed in.
+ - Add the vanilla extract and salt, and mix until combined.
+ - Sift in the flour, and mix until combined.
+ - Grease up the mixing bowl, to make it slightly sticky for the baking sheet.
+- label: Shaping
+ steps:
+ - Put the baking sheet into the mixing bowl, it does *not* need to look pretty!
+ - Ensure the baking sheet sticks out of the cake tin, along the sides, as the
+ cheesecake itself will rise way above the cake tin's height.
+ - Pour the cake batter from the mixing bowl into the cake tin.
+- label: Baking
+ steps:
+ - Bake the cheesecake for about 60 minutes.
+ - Let the cheesecake cool to room temperature.
+ - Refridgerate the cheesecake for at least 2 hours.
+---
+
+The easiest cheesecake you've ever made. Baked quickly and at a high temperature
+without regard for looking pretty.
diff --git a/content/recipes/snacks/kruidnoten.md b/content/recipes/snacks/kruidnoten.md
new file mode 100644
index 0000000..3613b95
--- /dev/null
+++ b/content/recipes/snacks/kruidnoten.md
@@ -0,0 +1,50 @@
+---
+title: Kruidnoten
+date: 2022-04-18
+tags:
+- snacks
+preptime: 60
+cooktime: 15
+serves: 2
+
+ingredients:
+- label: Baking Powder
+ amount: 3
+ unit: grams
+- label: Bastard Sugar (Dark)
+ amount: 60
+ unit: grams
+- label: Butter
+ amount: 70
+ unit: grams
+- label: Flour
+ amount: 100
+ unit: grams
+- label: Milk
+ amount: 25
+ unit: grams
+- label: Speculaas spices
+ amount: 6
+ unit: grams
+- label: Vanilla Extract
+ amount: 3
+ unit: grams
+
+stages:
+- label: Batter
+ steps:
+ - Put all ingredients in a mixing bowl
+ - Use a mixer with dough hooks to combine everything into a cohesive dough
+ - Take the dough out of the mixing bowl, and wrap it in plastic wrap
+ - Leave the wrapped dough in the fridge for 30 - 45 minutes to rest
+- label: Baking
+ steps:
+ - Take the dough out of the fridge
+ - Turn on the oven to 448K
+ - Take small bits of dough, and roll them into balls
+ - Put the dough balls on a baking sheet
+ - Bake the dough balls for 15 minutes
+ - Take the kruidnoten out of the oven, and let cool on a wire rack for 15 - 30 minutes
+---
+
+A Dutch snack for Sinterklaas, but very tasty at any time of the year.
diff --git a/content/services/_index.md b/content/services/_index.md
new file mode 100644
index 0000000..f303c7a
--- /dev/null
+++ b/content/services/_index.md
@@ -0,0 +1,12 @@
+---
+title: Services
+---
+
+These are all the services I run for public use. I give no guarantee on the
+stability of any of these services, nor the longevity of them.
+
+<ul>
+{{ range .Pages }}
+ <li><a href="{{ .Permalink }}">{{ .Title }}</a></li>
+{{ end }}
+</ul>
diff --git a/content/services/fiche.md b/content/services/fiche.md
new file mode 100644
index 0000000..62e0fe8
--- /dev/null
+++ b/content/services/fiche.md
@@ -0,0 +1,12 @@
+---
+title: Fiche
+location: https://p.tyil.nl
+upstream: https://github.com/solusipse/fiche
+---
+
+Fiche is a service to host pastes, which can be sent to it through various
+command line utilities. The easiest way to create a new paste is with `nc`.
+
+```sh
+$command | nc tyil.nl 9999
+```
diff --git a/content/services/invidious.md b/content/services/invidious.md
new file mode 100644
index 0000000..211879f
--- /dev/null
+++ b/content/services/invidious.md
@@ -0,0 +1,8 @@
+---
+title: Invidious
+location: https://youtube.alt.tyil.nl
+upstream: https://github.com/iv-org/invidious
+---
+
+Invidious is an alternative front-end to YouTube. It greatly diminishes the
+amount of JavaScript required to watch content.
diff --git a/content/services/nitter.md b/content/services/nitter.md
new file mode 100644
index 0000000..5bb111a
--- /dev/null
+++ b/content/services/nitter.md
@@ -0,0 +1,8 @@
+---
+title: Nitter
+location: https://twitter.alt.tyil.nl
+upstream: https://github.com/zedeus/nitter
+---
+
+Nitter is an alternative front-end to Twitter, which uses no JavaScript at all
+to render the posts and comments. It also supports RSS feeds for user profiles.
diff --git a/content/services/omgur.md b/content/services/omgur.md
new file mode 100644
index 0000000..68c73ee
--- /dev/null
+++ b/content/services/omgur.md
@@ -0,0 +1,9 @@
+---
+title: Omgur
+location: https://imgur.alt.tyil.nl
+upstream: https://github.com/geraldwuhoo/omgur
+---
+
+Omgur is a JavaScript free alternative front-end to Imgur. This project does
+not include a "front page", only pages which show actual uploaded content are
+implemented.
diff --git a/content/services/searxng.md b/content/services/searxng.md
new file mode 100644
index 0000000..abdcaa2
--- /dev/null
+++ b/content/services/searxng.md
@@ -0,0 +1,9 @@
+---
+title: SearxNG
+location: https://searxng.tyil.nl
+upstream: https://docs.searxng.org/
+---
+
+SearXNG is a free internet metasearch engine which aggregates results from more
+than 70 search services. Users are neither tracked nor profiled. It is a fork of
+Searx.
diff --git a/content/services/teddit.md b/content/services/teddit.md
new file mode 100644
index 0000000..a8eff08
--- /dev/null
+++ b/content/services/teddit.md
@@ -0,0 +1,8 @@
+---
+title: Teddit
+location: https://reddit.alt.tyil.nl
+upstream: https://github.com/teddit-net/teddit
+---
+
+Teddit as an alternative front-end to Reddit, without the need for any
+JavaScript to operate.
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
new file mode 100644
index 0000000..f69ca6a
--- /dev/null
+++ b/layouts/_default/baseof.html
@@ -0,0 +1,54 @@
+{{- $cssMain := resources.Get "theme/main.scss" | resources.ToCSS | fingerprint -}}
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="canonical" class="u-url" href="{{ .Permalink }}">
+ <link rel="stylesheet" type="text/css" href="{{ $cssMain.Permalink }}">
+ <link rel="me" href="https://fedi.tyil.nl/@tyil">
+ <link rel="me" href="https://git.tyil.nl">
+ <link rel="me" href="https://sr.ht/~tyil">
+ <link rel="me" href="https://www.tyil.nl" class="h-card">
+ <link rel="me" href="mailto:p.spek@tyil.nl">
+ {{- range .AlternativeOutputFormats }}
+ <link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" title="{{ $.Site.Title }}" href="{{ .Permalink }}">
+ {{- end }}
+ <title>{{ .Page.Title }} - {{ .Site.Title }}</title>
+ {{- block "head" . }}
+ {{- end }}
+ </head>
+ <body>
+ {{- block "body" . }}
+ <header id="site-header">
+ <div class="container">
+ <nav class="main">
+ <a href="/" class="brand-name">{{ .Site.Title }}</a>
+ {{- range sort .Site.Sections "Title" }}
+ <a href="{{ .Permalink }}">{{ .Title }}</a>
+ {{- end }}
+ </nav>
+ </div>
+ </header>
+ <main id="site-main">
+ <div class="container">
+ {{- block "main" . }}{{ end }}
+ </div>
+ </main>
+ <footer id="site-footer">
+ <div class="container">
+ <hr>
+ <p>&copy; 2016 - {{ now.Year }} &ndash; Patrick "tyil" Spek</p>
+ <p>
+ All content is licensed as per the license shown below
+ that content. All other sources (html, css, ...) are
+ released under the terms of the <a
+ href="https://www.gnu.org/licenses/gpl-3.0.txt">GNU GPL,
+ version 3</a> or later.
+ </p>
+ </div>
+ </footer>
+ {{- end }}
+ </body>
+</html>
diff --git a/layouts/_default/list.html b/layouts/_default/list.html
new file mode 100644
index 0000000..6ba66fc
--- /dev/null
+++ b/layouts/_default/list.html
@@ -0,0 +1,11 @@
+{{- define "main" }}
+<h1>{{ .Title }}</h1>
+{{ .Content }}
+<ul>
+ {{- range .Paginator.Pages }}
+ <li>
+ <a href="{{ .Permalink }}">{{ .Title }}</a>
+ </li>
+ {{- end }}
+</ul>
+{{- end }}
diff --git a/layouts/_default/single.html b/layouts/_default/single.html
new file mode 100644
index 0000000..79dc350
--- /dev/null
+++ b/layouts/_default/single.html
@@ -0,0 +1,10 @@
+{{ define "main" }}
+<article>
+ <header>
+ <h1>{{ .Title }}</h1>
+ </header>
+ <main>
+ {{ .Content }}
+ </main>
+</article>
+{{ end }}
diff --git a/layouts/_default/term.html b/layouts/_default/term.html
new file mode 100644
index 0000000..ee63c70
--- /dev/null
+++ b/layouts/_default/term.html
@@ -0,0 +1,19 @@
+{{ define "main" }}
+<h1>Posts tagged with #{{ .Title }}</h1>
+{{ .Content }}
+<ul>
+ {{ range .Paginator.Pages }}
+ <li>
+ <a href="{{ .Permalink }}">
+ {{ .Title }}
+ </a>
+ <small>
+ {{ .Date | dateFormat "2006-01-02" }}
+ {{- range .Params.tags }}
+ <a href="/tags/{{ . | lower }}">#{{ . }}</a>
+ {{- end }}
+ </small>
+ </li>
+ {{ end }}
+</ul>
+{{ end }}
diff --git a/layouts/home.html b/layouts/home.html
new file mode 100644
index 0000000..b1e0212
--- /dev/null
+++ b/layouts/home.html
@@ -0,0 +1,21 @@
+{{ define "main" }}
+<article>
+ <header>
+ <h1>
+ {{ .Page.Title }}
+ </h1>
+ <small>
+ </small>
+ </header>
+ <main>
+ {{ .Content }}
+ </main>
+ <footer>
+ <p class="text-center">
+ <a class="image-link" rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
+ <img alt="Creative Commons License" src="/img/cc-by-sa.png" />
+ </a>
+ </p>
+ </footer>
+</article>
+{{ end }}
diff --git a/layouts/posts/list.html b/layouts/posts/list.html
new file mode 100644
index 0000000..b5ec8ca
--- /dev/null
+++ b/layouts/posts/list.html
@@ -0,0 +1,22 @@
+{{- define "main" }}
+<h1>{{ .Title }}</h1>
+{{ .Content }}
+{{- range .Sections }}
+ <h2>{{ .Title }}</h2>
+ <ul>
+ {{- range .Pages }}
+ <li>
+ <a class="u-url" href="{{ .Permalink }}"><span class="p-name">{{ .Title }}</span></a>
+ <small>
+ <time class="dt-published" datetime="{{ .Date | dateFormat "2006-01-02" }}">
+ {{ .Date | dateFormat "2006-01-02" }}
+ </time>
+ {{- range .Params.tags }}
+ <a class="p-category tag" href="/tags/{{ . | lower }}">{{ . }}</a>
+ {{- end }}
+ </small>
+ </li>
+ {{- end }}
+ </ul>
+{{- end }}
+{{- end }}
diff --git a/layouts/posts/list.xml b/layouts/posts/list.xml
new file mode 100644
index 0000000..deb2448
--- /dev/null
+++ b/layouts/posts/list.xml
@@ -0,0 +1,37 @@
+{{- $pctx := . -}}
+{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
+{{- $pages := slice -}}
+{{- range .Sections.Reverse -}}
+{{- $pages = (append $pages (where .RegularPages "Draft" false)) }}
+{{- end -}}
+{{- $limit := .Site.Config.Services.RSS.Limit -}}
+{{- if ge $limit 1 -}}
+{{- $pages = $pages | first $limit -}}
+{{- end -}}
+{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
+ <link>{{ .Permalink }}</link>
+ <description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
+ <generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
+ <language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
+ <managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
+ <webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
+ <copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
+ <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
+ {{- with .OutputFormats.Get "RSS" -}}
+ {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
+ {{- end -}}
+ {{ range $pages }}
+ <item>
+ <title>{{ .Title }}</title>
+ <link>{{ .Permalink }}</link>
+ <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
+ {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
+ <guid>{{ .Permalink }}</guid>
+ <description>{{ .Content | html }}</description>
+ </item>
+ {{ end }}
+ </channel>
+</rss>
diff --git a/layouts/posts/single.html b/layouts/posts/single.html
new file mode 100644
index 0000000..eca87b9
--- /dev/null
+++ b/layouts/posts/single.html
@@ -0,0 +1,36 @@
+{{ define "main" }}
+<article class="h-entry">
+ <header>
+ <h1 class="p-name">{{ .Title }}</h1>
+ <p>
+ {{- range .Params.tags }}
+ <a class="p-category tag" href="/tags/{{ . | lower }}">{{ . }}</a>
+ {{- end }}
+ &mdash; Published on <time class="dt-published" datetime="{{ .Date | dateFormat "2006-01-02" }}">{{ .Date | dateFormat "2006-01-02" }}</time>.
+ </p>
+ {{- if .Draft }}
+ <section class="admonition">
+ <div class="admonition-title">
+ draft
+ </div>
+ <div class="admonition-content">
+ This blog post is still a
+ <strong>draft</strong>. It has most likely been
+ shared with you for reviewing purposes. Please
+ do not yet share this with other people.
+ </div>
+ </section>
+ {{- end }}
+ </header>
+ <main class="e-content">
+ {{ .Content }}
+ </main>
+ <footer>
+ <p class="text-center">
+ <a class="image-link" rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
+ <img alt="Creative Commons License" src="/img/cc-by-sa.png">
+ </a>
+ </p>
+ </footer>
+</article>
+{{ end }}
diff --git a/layouts/project-release/list.html b/layouts/project-release/list.html
new file mode 100644
index 0000000..b52dd0e
--- /dev/null
+++ b/layouts/project-release/list.html
@@ -0,0 +1,14 @@
+{{- define "main" }}
+<h1>{{ .Parent.Title }} Releases</h1>
+{{ .Content }}
+<ul>
+ {{- range .Pages }}
+ <li>
+ <a href="{{ .Permalink }}">{{ .Title }}</a>
+ ({{ .Date | dateFormat "2006-01-02" }})
+ </li>
+ {{- end }}
+</ul>
+<p>Follow the <a href="{{ .Permalink }}index.xml">RSS feed</a> to stay up to date with
+the latest {{ .Parent.Title }} releases.</p>
+{{- end }}
diff --git a/layouts/project-release/list.xml b/layouts/project-release/list.xml
new file mode 100644
index 0000000..74cdda2
--- /dev/null
+++ b/layouts/project-release/list.xml
@@ -0,0 +1,27 @@
+{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>{{ .Title }}</title>
+ <link>{{ .Permalink }}</link>
+ <description>{{ .Title }} Releases</description>
+ <generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
+ <language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
+ <managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
+ <webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
+ <copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
+ <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
+ {{- with .OutputFormats.Get "RSS" -}}
+ {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
+ {{- end -}}
+ {{ range .Pages }}
+ <item>
+ <title>{{ .Title }}</title>
+ <link>{{ .Permalink }}</link>
+ <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
+ {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
+ <guid>{{ .Permalink }}</guid>
+ <description>{{ .Content | html }}</description>
+ </item>
+ {{ end }}
+ </channel>
+</rss>
diff --git a/layouts/project-release/single.html b/layouts/project-release/single.html
new file mode 100644
index 0000000..e422699
--- /dev/null
+++ b/layouts/project-release/single.html
@@ -0,0 +1,20 @@
+{{ define "main" }}
+<article>
+ <header>
+ <h1>{{ .Title }}</h1>
+ </header>
+ <main>
+ {{ .Content }}
+ </main>
+ <footer>
+ {{- with .Params.packages }}
+ Pre-built packages:
+ <ul>
+ {{- range $key, $value := . }}
+ <li><a href="{{ $value }}">{{ $key }}</a></li>
+ {{- end }}
+ </ul>
+ {{- end }}
+ </footer>
+</article>
+{{ end }}
diff --git a/layouts/projects/list.html b/layouts/projects/list.html
new file mode 100644
index 0000000..de50a9c
--- /dev/null
+++ b/layouts/projects/list.html
@@ -0,0 +1,21 @@
+{{- define "main" }}
+<h1>{{ .Title }}</h1>
+{{ .Content }}
+{{- range .Sections }}
+ <section class="project">
+ <h2>
+ {{ .Title }}
+ <small>
+ {{- range .Params.languages }}
+ {{ . }}
+ {{- end }}
+ </small>
+ </h2>
+ {{ .Content }}
+ <nav class="project">
+ <a href="{{ .Permalink }}releases">Releases</a>
+ <a href="{{ .Params.repository }}">Sources</a>
+ </nav>
+ </section>
+{{- end }}
+{{- end }}
diff --git a/layouts/recipes/list.html b/layouts/recipes/list.html
new file mode 100644
index 0000000..b758a2b
--- /dev/null
+++ b/layouts/recipes/list.html
@@ -0,0 +1,24 @@
+{{- define "main" }}
+<h1>{{ .Title }}</h1>
+{{ .Content }}
+{{- range sort .Pages "Title" }}
+<section class="recipe">
+ <div class="preview">
+ {{- with .Params.preview }}
+ <img src="{{ .src }}" />
+ {{- end }}
+ </div>
+ <div class="description">
+ <h2>
+ <a class="p-name" href="{{ .Permalink }}">{{ .Title }}</a>
+ </h2>
+ <ul class="taglist">
+ {{- range sort .Params.tags }}
+ <li><a class="p-category tag" href="/tags/{{ . | lower }}">{{ . }}</a></li>
+ {{- end }}
+ </ul>
+ {{ .Content }}
+ </div>
+</section>
+{{- end }}
+{{- end }}
diff --git a/layouts/recipes/single.html b/layouts/recipes/single.html
new file mode 100644
index 0000000..353abd2
--- /dev/null
+++ b/layouts/recipes/single.html
@@ -0,0 +1,103 @@
+{{ define "main" }}
+<article>
+ <header>
+ <h1 class="p-name">{{ .Title }}</h1>
+ <ul class="taglist">
+ {{- range sort .Params.tags }}
+ <li><a class="p-category tag" href="/tags/{{ . | lower }}">{{ . }}</a></li>
+ {{- end }}
+ </ul>
+ {{- if .Draft }}
+ <section class="admonition">
+ <div class="admonition-title">
+ draft
+ </div>
+ <div class="admonition-content">
+ This recipe is still a <strong>draft</strong>.
+ It has most likely been shared with you for
+ reviewing purposes, but neither the
+ instructions nor the ingredients have been
+ properly checked yet. Do not make this recipe
+ unless you are an experienced cook, and please
+ do not yet share it with other people.
+ </div>
+ </section>
+ {{- end }}
+ </header>
+ <main class="e-content">
+ {{ .Content }}
+ <table>
+ <tbody>
+ <tr>
+ <td>Preparation time</td>
+ <td>{{ .Params.preptime }} minutes</td>
+ </tr>
+ <tr>
+ <td>Cooking time</td>
+ <td>{{ .Params.cooktime }} minutes</td>
+ </tr>
+ <tr>
+ <td>Serves</td>
+ <td data-serves="{{ .Params.serves }}">{{ .Params.serves }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <h2>Ingredients</h2>
+ <table>
+ <thead>
+ <tr>
+ <th>&nbsp;</th>
+ <th>Ingredient</th>
+ <th>Amount</th>
+ <th>Unit</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{- range $i, $ingredient := .Params.ingredients }}
+ <tr>
+ <td>
+ <input id="ingredient{{ $i }}" type="checkbox">
+ </td>
+ <td>
+ <label for="ingredient{{ $i }}">{{ .label }}</label>
+ {{- if .links }}
+ {{- range .links }}
+ <a class="external-link-icon" href="{{ . }}">↗</span></a>
+ {{- end }}
+ {{- end }}
+ </td>
+ {{- if .unit }}
+ <td data-unit="{{ $ingredient.unit }}" data-amount="{{ $ingredient.amount }}">{{ .amount }}</td>
+ <td data-unit="{{ $ingredient.unit }}">{{ $ingredient.unit }}</td>
+ {{- else }}
+ <td colspan="2">{{ $ingredient.amount }}</td>
+ {{- end }}
+ </tr>
+ {{- end }}
+ </tbody>
+ </table>
+ <h2>Instructions</h2>
+ {{- range $i, $stage := .Params.stages }}
+ <h3>{{ $stage.label }}</h3>
+ {{- if $stage.notes }}
+ <p>{{ .notes }}</p>
+ {{- end }}
+ <ol>
+ {{- range $j, $step := $stage.steps }}
+ <li>
+ <input id="stage{{ $i }}-step{{ $j }}" type="checkbox">
+ <label for="stage{{ $i }}-step{{ $j }}">{{ $step | $.Page.RenderString }}</label>
+ </li>
+ {{- end }}
+ </ol>
+ {{- end }}
+ </main>
+ <footer>
+ <p class="text-center">
+ <a class="image-link" rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
+ <img alt="Creative Commons License" src="/img/cc-by-sa.png">
+ </a>
+ </p>
+ </footer>
+</article>
+{{ end }}
diff --git a/layouts/services/list.html b/layouts/services/list.html
new file mode 100644
index 0000000..8e78be0
--- /dev/null
+++ b/layouts/services/list.html
@@ -0,0 +1,13 @@
+{{ define "main" }}
+<h1>{{ .Title }}</h1>
+{{ .Content }}
+{{ range .Pages }}
+<section class="service">
+ <h2>
+ {{ .Title }}
+ <small><a href="{{ .Params.location }}">{{ .Params.location }}</a></small>
+ </h2>
+ {{ .Content }}
+</section>
+{{ end }}
+{{ end }}
diff --git a/layouts/services/single.html b/layouts/services/single.html
new file mode 100644
index 0000000..e1afa52
--- /dev/null
+++ b/layouts/services/single.html
@@ -0,0 +1,14 @@
+{{ define "main" }}
+<article>
+ <header>
+ <h1>{{ .Title }}</h1>
+ </header>
+ <main>
+ <ul>
+ <li><strong>Base URL</strong>: <a href="{{ .Params.location }}">{{ .Params.location }}</a></li>
+ <li><strong>Upstream</strong>: <a href="{{ .Params.upstream }}">{{ .Params.upstream }}</a></li>
+ </ul>
+ {{ .Content }}
+ </main>
+</article>
+{{ end }}
diff --git a/layouts/shortcodes/admonition.html b/layouts/shortcodes/admonition.html
new file mode 100644
index 0000000..f25b9ff
--- /dev/null
+++ b/layouts/shortcodes/admonition.html
@@ -0,0 +1,8 @@
+<section class="admonition">
+ <div class="admonition-title">
+ {{ .Get "title" }}
+ </div>
+ <div class="admonition-content">
+ {{ .Inner | .Page.RenderString }}
+ </div>
+</section>
diff --git a/layouts/shortcodes/quote.html b/layouts/shortcodes/quote.html
new file mode 100644
index 0000000..f2d9c4c
--- /dev/null
+++ b/layouts/shortcodes/quote.html
@@ -0,0 +1,10 @@
+<div class="quoteblock">
+ <blockquote>
+ <div class="paragraph">
+ {{ .Inner | .Page.RenderString }}
+ </div>
+ </blockquote>
+ <div class="attribution">
+ — {{ .Get "attribution" }}
+ </div>
+</div>
diff --git a/share/feed-atom.xml b/share/feed-atom.xml
deleted file mode 100644
index b8df9ef..0000000
--- a/share/feed-atom.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "$TAG"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/share/feed-rss2.xml b/share/feed-rss2.xml
deleted file mode 100644
index f915f56..0000000
--- a/share/feed-rss2.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "$TAG"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/.docker/envvars.sh b/src/.docker/envvars.sh
deleted file mode 100644
index 71f47e1..0000000
--- a/src/.docker/envvars.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /usr/bin/env sh
-
-main()
-{
- mkvar intendedHost "${INTENDED_HOST:-localhost}"
- mkvar intendedHostProto "${INTENDED_HOST_PROTO:-http}"
-}
-
-mkvar()
-{
- printf 'var.%s="%s"\n' "$1" "$2"
-}
-
-main "$@"
diff --git a/src/.docker/lighttpd.conf b/src/.docker/lighttpd.conf
deleted file mode 100644
index 1b480ca..0000000
--- a/src/.docker/lighttpd.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-server.modules += (
- "mod_setenv",
- "mod_redirect",
-)
-
-setenv.add-response-header = (
- "Content-Security-Policy" => "default-src 'self'; img-src https:; object-src 'self'; script-src 'self'; style-src 'self'",
- "Referrer-Policy" => "no-referrer",
- "X-Content-Type-Options" => "nosniff",
- "X-Frame-Options" => "SAMEORIGIN",
- "X-Permitted-Cross-Domain-Policies" => "none",
- "X-XSS-Protection" => "1; mode=block",
-)
-
-include_shell "/usr/local/bin/lighttpd-env.sh"
-
-# Redirect to the "official" domain
-$HTTP["host"] != var.intendedHost {
- $HTTP["url"] !~ "^/.well-known" {
- url.redirect = ( "^/(.*)" => var.intendedHostProto + "://" + var.intendedHost + "/$1" )
- }
-}
-
-# Add CORS header for WKP
-$HTTP["url"] =~ "^/.well-known/openpgpkey" {
- setenv.add-response-header = (
- "Access-Control-Allow-Origin" => "*",
- )
-}
diff --git a/src/.well-known/openpgpkey/hu/i4fxxwcfae1o4d7wnb5bop89yfx399yf b/src/.well-known/openpgpkey/hu/i4fxxwcfae1o4d7wnb5bop89yfx399yf
deleted file mode 100644
index 132dcdf..0000000
--- a/src/.well-known/openpgpkey/hu/i4fxxwcfae1o4d7wnb5bop89yfx399yf
+++ /dev/null
Binary files differ
diff --git a/src/.well-known/openpgpkey/policy b/src/.well-known/openpgpkey/policy
deleted file mode 100644
index e69de29..0000000
--- a/src/.well-known/openpgpkey/policy
+++ /dev/null
diff --git a/src/Dockerfile b/src/Dockerfile
deleted file mode 100644
index cd97e8c..0000000
--- a/src/Dockerfile
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM registry.gitlab.com/tyil/docker-http-static:latest
-
-COPY _site /var/www
-COPY .docker/envvars.sh /usr/local/bin/lighttpd-env.sh
-COPY .docker/lighttpd.conf /etc/lighttpd/custom.d/lighttpd.conf
-
-RUN chmod +x /usr/local/bin/lighttpd-env.sh
diff --git a/src/Gemfile b/src/Gemfile
deleted file mode 100644
index 6430791..0000000
--- a/src/Gemfile
+++ /dev/null
@@ -1,11 +0,0 @@
-source "https://rubygems.org" do
- gem "jekyll"
- gem "jekyll-asciidoc"
- gem "jekyll-less"
- gem "jekyll-sitemap"
- gem "pygments.rb"
- gem "redcarpet"
- gem "therubyracer"
-end
-
-gem "jekyll-archives", "~> 2.2"
diff --git a/src/Gemfile.lock b/src/Gemfile.lock
deleted file mode 100644
index c884ccc..0000000
--- a/src/Gemfile.lock
+++ /dev/null
@@ -1,100 +0,0 @@
-GEM
- specs:
- jekyll-archives (2.2.1)
- jekyll (>= 3.6, < 5.0)
-
-GEM
- remote: https://rubygems.org/
- specs:
- addressable (2.7.0)
- public_suffix (>= 2.0.2, < 5.0)
- asciidoctor (2.0.15)
- colorator (1.1.0)
- commonjs (0.2.7)
- concurrent-ruby (1.1.8)
- em-websocket (0.5.2)
- eventmachine (>= 0.12.9)
- http_parser.rb (~> 0.6.0)
- eventmachine (1.2.7)
- ffi (1.15.0)
- forwardable-extended (2.6.0)
- http_parser.rb (0.6.0)
- i18n (1.8.10)
- concurrent-ruby (~> 1.0)
- jekyll (4.2.0)
- addressable (~> 2.4)
- colorator (~> 1.0)
- em-websocket (~> 0.5)
- i18n (~> 1.0)
- jekyll-sass-converter (~> 2.0)
- jekyll-watch (~> 2.0)
- kramdown (~> 2.3)
- kramdown-parser-gfm (~> 1.0)
- liquid (~> 4.0)
- mercenary (~> 0.4.0)
- pathutil (~> 0.9)
- rouge (~> 3.0)
- safe_yaml (~> 1.0)
- terminal-table (~> 2.0)
- jekyll-asciidoc (3.0.0)
- asciidoctor (>= 1.5.0)
- jekyll (>= 3.0.0)
- jekyll-less (0.0.4)
- jekyll (>= 0.10.0)
- less (>= 2.0.5)
- jekyll-sass-converter (2.1.0)
- sassc (> 2.0.1, < 3.0)
- jekyll-sitemap (1.4.0)
- jekyll (>= 3.7, < 5.0)
- jekyll-watch (2.2.1)
- listen (~> 3.0)
- kramdown (2.3.1)
- rexml
- kramdown-parser-gfm (1.1.0)
- kramdown (~> 2.0)
- less (2.6.0)
- commonjs (~> 0.2.7)
- libv8 (3.16.14.19)
- libv8 (3.16.14.19-x86_64-linux)
- liquid (4.0.3)
- listen (3.5.1)
- rb-fsevent (~> 0.10, >= 0.10.3)
- rb-inotify (~> 0.9, >= 0.9.10)
- mercenary (0.4.0)
- pathutil (0.16.2)
- forwardable-extended (~> 2.6)
- public_suffix (4.0.6)
- pygments.rb (2.2.0)
- rb-fsevent (0.11.0)
- rb-inotify (0.10.1)
- ffi (~> 1.0)
- redcarpet (3.5.1)
- ref (2.0.0)
- rexml (3.2.5)
- rouge (3.26.0)
- safe_yaml (1.0.5)
- sassc (2.4.0)
- ffi (~> 1.9)
- terminal-table (2.0.0)
- unicode-display_width (~> 1.1, >= 1.1.1)
- therubyracer (0.12.3)
- libv8 (~> 3.16.14.15)
- ref
- unicode-display_width (1.7.0)
-
-PLATFORMS
- ruby
- x86_64-linux
-
-DEPENDENCIES
- jekyll!
- jekyll-archives (~> 2.2)
- jekyll-asciidoc!
- jekyll-less!
- jekyll-sitemap!
- pygments.rb!
- redcarpet!
- therubyracer!
-
-BUNDLED WITH
- 2.2.16
diff --git a/src/README.adoc b/src/README.adoc
deleted file mode 100644
index b4b3110..0000000
--- a/src/README.adoc
+++ /dev/null
@@ -1,48 +0,0 @@
-= Tyil's blog
-:toc: preamble
-
-This is the repository containing my blog's sources. It's generated using
-Jekyll, and makes use of a few custom plugins to allow me to work the way I
-prefer.
-
-== For proofreaders
-
-If you got linked to this repository as a proofreader, you may want to check
-out the branch I've asked you to proofread, and serve it locally. This reads
-much easier than the source files for most people. To do this, you will need
-the Ruby `bundle` program. Refer to your distribution's package repositories to
-find out the package name, and how to install it.
-
-=== Cloning and serving locally
-
-To get the correct branch, and serve it locally, you'll need to go through the
-following steps:
-
- cd "$(mktemp -d)"
- git clone https://gitlab.com/tyil/blog.git .
- git fetch -a
- git checkout <branch-name>
- bundle install
- bundle exec jekyll s
-
-If everything goes well, this should make the website available on
-`http://localhost:4000`.
-
-=== Leaving feedback
-
-Feedback is easiest to send to me through email, or leave as (line) comments on
-the merge request for the given branch. This is easiest for me to work through,
-and read back at a later date if needed. I don't always have time to
-immediately fix certain issues that have been found.
-
-== For interested visitors
-
-Any feedback would be much appreciated to be sent to my mailbox,
-`p.spek@tyil.work`. My PGP key ID is `0x7A6AC285E2D98827`, please use this to
-encrypt mail sent to me, and use your own key to sign the contents as well.
-
-== License
-
-All code found in this repository is licensed under the GNU General Public
-License, version 3 or later, except where explicitly mentioned differently. The
-content itself has licenses attached to it on their respective pages.
diff --git a/src/_config.yml b/src/_config.yml
deleted file mode 100644
index 2f721a6..0000000
--- a/src/_config.yml
+++ /dev/null
@@ -1,77 +0,0 @@
-# Welcome to Jekyll!
-#
-# This config file is meant for settings that affect your whole blog, values
-# which you are expected to set up once and rarely need to edit after that.
-# For technical reasons, this file is *NOT* reloaded automatically when you use
-# 'jekyll serve'. If you change this file, please restart the server process.
-
-# Site settings
-title: Tyil
-author: Patrick Spek
-email: p.spek@tyil.work
-description: >
- The blog of Patrick "tyil" Spek, a software engineer who loves free software,
- and the Raku programming language in particular. On this blog I'll
- occasionally publish a post to tell something about something cool I
- discovered, or to help people accomplish a certain task that I can help them
- with.
-baseurl: "" # the subpath of your site, e.g. /blog
-url: "https://www.tyil.nl" # the base hostname & protocol for your site
-permalink: pretty
-plugins:
- - jekyll-archives
- - jekyll-asciidoc
- - jekyll-sitemap
- - pygments.rb
-
-keep_files:
- - img
-asciidoctor:
- attributes:
- imagesdir: /img
- source-highlighter: pygments
-sass:
- style: compressed
-
-exclude:
- - bin
-
-# Build settings
-markdown: kramdown
-highlighter: pygments
-
-include: [
- ".well-known",
- "_pages",
-]
-
-# custom collections
-collections:
- projects:
- output: true
- slides:
- output: false
-
-jekyll-archives:
- enabled:
- - tags
- layout: archive
- permalinks:
- tag: /tag/:name/
-
-# Give all posts a feed = true attribute for easy feed-generating
-defaults:
- - scope:
- type: posts
- values:
- feed: true
- category: Post
- - scope:
- type: projects
- values:
- feed: true
- categories: Project
- - scope:
- type: slides
- values:
- feed: false
diff --git a/src/_includes/footer.html b/src/_includes/footer.html
deleted file mode 100644
index e1f6637..0000000
--- a/src/_includes/footer.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-<footer class="site-footer">
- <div class="container">
- <hr>
- <p>&copy; 2016 - {{ 'now' | date: "%Y" }} &ndash; Patrick "tyil" Spek</p>
- <p>
- All content is licensed as per the license shown below that content.
- All other sources (html, css, ...) are released under the terms of the
- <a href="https://www.gnu.org/licenses/gpl-3.0.txt">GNU GPL, version
- 3</a> or later.
- </p>
- <p>
- Site generated using Jekyll from <a
- href="https://gitlab.com/tyil/blog">this git repository</a>. The link
- to the Jekyll site is intentionally omitted as they make use of
- Cloudflare. Until this issue is resolved, I will not link to them.
- </p>
- </div>
-</footer>
diff --git a/src/_includes/head.html b/src/_includes/head.html
deleted file mode 100644
index 78ef1f7..0000000
--- a/src/_includes/head.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-<head lang="en">
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1">{% if page.description %}
- <meta name="description" content="{{ page.description | strip_newlines }}" />
-{% endif %}
- <link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
- <link rel="stylesheet" type="text/css" href="{{ "/css/pygments.css" | prepend: site.baseurl }}" />
- <link rel="stylesheet" type="text/css" href="{{ "/css/main.css" | prepend: site.baseurl }}" />
- <link rel="alternate" type="application/atom+xml" title="{{ site.title }}" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}">
- <link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}">
-
- <title>{% if page.title %}{{ page.title }} - {% endif %}{{ site.title }}</title>
-</head>
diff --git a/src/_includes/header.html b/src/_includes/header.html
deleted file mode 100644
index 9c0a8e5..0000000
--- a/src/_includes/header.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<header id="site-header">
- <div class="container">
- <nav>
- <a href="{{ site.baseurl }}/" class="brand-name">{{ site.title }}</a>{% for collection in site.collections %}
- <a href="{{ collection.label | prepend: "/" | prepend: site.baseurl }}/">{{ collection.label | capitalize }}</a>{% endfor %}
- <a href="{{ "/support" | prepend: site.baseurl }}/">Support me</a>
- </nav>
- </div>
-</header>
diff --git a/src/_includes/posts-intro.md b/src/_includes/posts-intro.md
deleted file mode 100644
index c109af2..0000000
--- a/src/_includes/posts-intro.md
+++ /dev/null
@@ -1,22 +0,0 @@
-{% markdown %}
-Over time, I've written a number of articles. Some to voice my opinion, some to
-help people out with a tutorial. These articles are listed below, sorted by
-publication date. If you have any comments on any of my articles, feel free to
-reach out to me through any of the contact details found [on the
-homepage][home]. Alternatively, I have a public inbox on Sourcehut that you
-can send any comments to:
-[`~tyil/public-inbox@lists.sr.ht`](mailto:~tyil/public-inbox@lists.sr.ht).
-
-All my blog posts are available under the [Creative Commons (CC BY-SA
-3.0)][cc-by-sa] license, which means you are free to use it for any purpose so
-long as you keep attribution to me (and preferably also just link to the
-original article) and do not relicense the article.
-
-I'd also like to note that **these articles reflect my opinion, and only
-mine**. Please refrain from accusing other people of holding my opinion for
-simply being referenced in my articles.
-
-[cc-by-sa]: https://creativecommons.org/licenses/by-sa/3.0/
-[home]: /
-[pgp]: http://pgp.mit.edu/pks/lookup?op=vindex&search=0x7A6AC285E2D98827
-{% endmarkdown %}
diff --git a/src/_layouts/archive.html b/src/_layouts/archive.html
deleted file mode 100644
index c794c22..0000000
--- a/src/_layouts/archive.html
+++ /dev/null
@@ -1,39 +0,0 @@
----
-layout: default
----
-
-{% markdown %}
-## Blog posts tagged with #{{ page.title | slugify }}
-{% endmarkdown %}
-
-{% include posts-intro.md %}
-
-{% for post in page.posts %}
- {% if post.wip %}{% continue %}{% endif %}
- {% assign this_year = post.date | date: "%Y" %}
-
- {% if this_year != prev_year %}
- {% if forloop.first != true %}
- </ul>
- {% endif %}
-
- <h3>{{ this_year }}</h3>
- <ul>
- {% endif %}
-
- <li>
- <a href="{{ post.url }}">{{ post.title }}</a>
- <small>
- {{ post.date | date: "%Y-%m-%d" }}
- {% for tag in post.tags %}
- <a href="{{ site.baseurl | prepend: site.url }}/tag/{{ tag | slugify }}">#{{ tag | slugify }}</a>
- {% endfor %}
- </small>
- </li>
-
- {% if forloop.last %}
- </ul>
- {% endif %}
-
- {% assign prev_year = post.date | date: "%Y" %}
-{% endfor %}
diff --git a/src/_layouts/default.html b/src/_layouts/default.html
deleted file mode 100644
index 228f4c7..0000000
--- a/src/_layouts/default.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{% include head.html %}
- <body>
-{% include header.html %}
- <main>
- <div class="container">
-{{ content }} </div>
- </main>
-{% include footer.html %}
- </body>
-</html>
diff --git a/src/_layouts/language-war.html b/src/_layouts/language-war.html
deleted file mode 100644
index 31f1085..0000000
--- a/src/_layouts/language-war.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head lang="en">
- {% include head.html %}
- <link rel="stylesheet" type="text/css" href="{{ "/css/language-war.css" | prepend: site.baseurl }}" />
- </head>
- <body>
- {% include header.html %}
- <article>
- <main>
- {{ content }}
- </main>
- <footer>
- <p class="text-center">
- <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
- <img alt="Creative Commons License" style="border-width:0" src="{{ "/img/cc-by-sa.png" | prepend: site.baseurl }}" />
- </a>
- </p>
- {% if page.authors %}
- <p>
- This <span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">work</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
- You can freely modify and redistribute this work as long as attribution to the author(s) remains:
- </p>
- <ul>
- {% for author in page.authors %}
- <li>
- {% if author[1] %}
- <a xmlns:cc="http://creativecommons.org/ns#" href="{{ author[1] }}" property="cc:attributionName" rel="cc:attributionURL">{{ author[0] }}</a>
- {% else %}
- {{ author[0] }}
- {% endif %}
- </li>
- {% endfor %}
- </ul>
- {% endif %}
- </footer>
- </article>
- {% include footer.html %}
- </body>
-</html>
diff --git a/src/_layouts/post.html b/src/_layouts/post.html
deleted file mode 100644
index d979adb..0000000
--- a/src/_layouts/post.html
+++ /dev/null
@@ -1,51 +0,0 @@
----
-layout: default
----
-
-<article>
- <header>
- <h1>
- {{ page.title }}
- {% if page.wip %}<small>Work in progress!</small>{% endif %}
- </h1>
- <small>
- {% for tag in page.tags %}
- <a href="{{ site.baseurl | prepend: site.url }}/tag/{{ tag | slugify }}">#{{ tag | slugify }}</a>
- {% endfor %}
- </small>
- </header>
- <main>
- {{ content }}
- </main>
- <footer>
- <p class="text-center">
- <a class="image-link" rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
- <img alt="Creative Commons License" style="border-width:0" src="{{ "/img/cc-by-sa.png" | prepend: site.baseurl }}" />
- </a>{% if page.social %}
- <span class="footer-link-seperator"></span>
- {% for media in page.social %}
- <a class="image-link" href="{{ media[1] }}">
- <img alt="{{ media[0] }}" src="{{ media[0] | append: ".png" | prepend: "/img/" | prepend: site.baseurl }}" />
- </a>
- {% endfor %}
- {% endif %}
- </p>
- {% if page.authors %}
- <p>
- This <span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">work</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
- You can freely modify and redistribute this work as long as attribution to the author(s) remains:
- </p>
- <ul>
- {% for author in page.authors %}
- <li>
- {% if author[1] %}
- <a xmlns:cc="http://creativecommons.org/ns#" href="{{ author[1] }}" property="cc:attributionName" rel="cc:attributionURL">{{ author[0] }}</a>
- {% else %}
- {{ author[0] }}
- {% endif %}
- </li>
- {% endfor %}
- </ul>
- {% endif %}
- </footer>
-</article>
diff --git a/src/_layouts/project.html b/src/_layouts/project.html
deleted file mode 100644
index e85b209..0000000
--- a/src/_layouts/project.html
+++ /dev/null
@@ -1,22 +0,0 @@
----
-layout: default
----
-
-<article>
- <header>
- <h1>{{ page.title }}</h1>
- </header>
- <main>
- {{ content }}
- </main>
- <footer>
- <hr>
- <ul>
- <li><strong>Language(s)</strong>: {{ page.langs }}</li>
- <li><strong>License</strong>: {{ page.license }}</li>
- <li>
- <strong>Source repository</strong>: <a href="{{ page.repo}}">{{ page.repo }}</a>
- </li>
- </ul>
- </footer>
-</article>
diff --git a/src/_pages/blank.md b/src/_pages/blank.md
deleted file mode 100644
index 64dffe5..0000000
--- a/src/_pages/blank.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-permalink: /blank/
----
diff --git a/src/_pages/index.html b/src/_pages/index.html
deleted file mode 100644
index 12c368b..0000000
--- a/src/_pages/index.html
+++ /dev/null
@@ -1,108 +0,0 @@
----
-layout: default
-permalink: /index.html
-title: Personal blog
-description: >
- Hi, I'm tyil, and this is my site. I'm a software engineer with a big
- interest in Free Software. As such, I spend much time writing and promoting
- free software. Occasionally, I'll write an article about something freedom or
- software related.
----
-
-{% for post in site.posts %}{% if post.wip %}{% continue %}{% endif %}{% assign blogpost = post %}{% break %}{% endfor %}
-{% markdown %}
-## About me
-
-Freedom-focused hacker. I love everything about free software, and spend much
-time contributing to it myself. I occasionally write articles to help other
-people getting started with free software, and show the issues with proprietary
-software. I'm active on a number of IRC channels, spread over multiple IRC
-networks. My favourite language by far is the Raku programming language. I also
-write a blog post on occasion, with my latest write-up being
-"[{{blogpost.title}}]({{blogpost.url}})".
-
-If you think what I'm doing is awesome, and want to support me, you can do so
-through donations. More information about how to donate and what I do with the
-donations I receive can be found on the [support][donate] page.
-
-## Contact
-
-### PGP
-
-My public PGP key is available [from my own site][pubkey], or from a public key
-server such as [pgp.mit.edu][pubkey-mit]. The fingerprint is:
-
- 1660 F6A2 DFA7 5347 322A 4DC0 7A6A C285 E2D9 8827
-
-You can also fetch my PGP key using the
-[WebKey Protocol]({{ "/post/2020/05/30/setting-up-pgp-wkd/" | prepend: site.baseurl | prepend: site.url }}):
-
- gpg --locate-key p.spek@tyil.nl
-
-### OTR
-
-For instant messaging I use OTR where possible. My fingerprints are the following:
-
-- `973F92EA 4A45DE93 60C2C60E DDC049D5 149B3BE2` XMPP, tyil@national.shitposting.agency
-- `B174A02B 1F0A4258 B1527988 770843B4 0582A0D8` IRC, tyil @ DareNET
-- `C6025214 E05A4FB6 5E65B900 9CA6A7AF A4A35C48` IRC, tyil @ Freenode
-- `80999DD8 22504629 44EC13E3 5C31BF2F FC825703` IRC, tyil @ Rizon
-
-[donate]: {{ "/support/" | prepend: site.baseurl | prepend: site.url }}
-[pubkey-mit]: http://pgp.mit.edu/pks/lookup?op=vindex&search=0x7A6AC285E2D98827
-[pubkey]: {{ "/pubkey.txt" | prepend: site.baseurl | prepend: site.url }}
-{% endmarkdown %}
-<h3 id="communication-channels">Channels</h3>
-{% markdown %}
-
-#### Email
-
-Email contact goes via [p.spek@tyil.work][mail]. Be sure to at least sign all
-mail you send me. Even better would be encrypted mail using my [PGP
-key][pubkey].
-
-I do not read my mailboxes very often, so please do not expect a timely
-response. If you require a response as soon as possible, please find me on IRC
-instead.
-
-#### IRC
-
-I am mainly active as `tyil` on [Freenode][freenode]. Other networks I frequent
-are [DareNET][darenet] and [Rizon][rizon], using the same nick, `tyil`. I
-use OTR for private messages on IRC, so be sure you use this if you want to
-discuss something in private.
-
-#### Fediverse
-
-I have a presence on the Fediverse, on the [Friendly GNU/Linux
-Fediverse][fediverse-fglt] instance, where I go by the username of
-[`tyil`][fediverse].
-
-## Other links
-
-- [Sourcehut account][git-srht]
-- [GitLab account][git-gl]
-- [GitHub account][git-gh]
-- [LinkedIn][linkedin]
-
-## RSS
-
-If you'd like to stay up-to-date with my posts, you can subscribe to the [RSS
-feed][rss] or the [Atom feed][atom].
-
-[atom]: {{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}
-[darenet]: https://darenet.org
-[fediverse-fglt]: https://soc.fglt.nl/
-[fediverse]: https://soc.fglt.nl/tyil
-[freenode]: https://freenode.net
-[git-gh]: https://github.com/tyil
-[git-gl]: https://gitlab.com/tyil
-[git-srht]: https://sr.ht/~tyil/
-[keybase]: https://keybase.io/tyil
-[linkedin]: https://www.linkedin.com/in/patrickspek
-[mail]: mailto:p.spek@tyil.work
-[mastodon]: https://mastodon.social/web/accounts/34234
-[pubkey]: {{ "/pubkey.txt" | prepend: site.baseurl | prepend: site.url }}
-[rizon]: https://rizon.net
-[rss]: {{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}
-{% endmarkdown %}
diff --git a/src/_pages/posts.html b/src/_pages/posts.html
deleted file mode 100644
index 4f10758..0000000
--- a/src/_pages/posts.html
+++ /dev/null
@@ -1,44 +0,0 @@
----
-layout: default
-permalink: /posts/
-title: Blog posts
-description: >
- I occasionally write blogposts about things I find interesting. These are
- usually programming, security or privacy related.
----
-
-{% markdown %}
-## Blog posts
-{% endmarkdown %}
-
-{% include posts-intro.md %}
-
-{% for post in site.posts %}
- {% if post.wip %}{% continue %}{% endif %}
- {% assign this_year = post.date | date: "%Y" %}
-
- {% if this_year != prev_year %}
- {% if forloop.first != true %}
- </ul>
- {% endif %}
-
- <h3>{{ this_year }}</h3>
- <ul>
- {% endif %}
-
- <li>
- <a href="{{ post.url }}">{{ post.title }}</a>
- <small>
- {{ post.date | date: "%Y-%m-%d" }}
- {% for tag in post.tags %}
- <a href="{{ site.baseurl | prepend: site.url }}/tag/{{ tag | slugify }}">#{{ tag | slugify }}</a>
- {% endfor %}
- </small>
- </li>
-
- {% if forloop.last %}
- </ul>
- {% endif %}
-
- {% assign prev_year = post.date | date: "%Y" %}
-{% endfor %}
diff --git a/src/_pages/projects.md b/src/_pages/projects.md
deleted file mode 100644
index 3b6a89f..0000000
--- a/src/_pages/projects.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-layout: default
-permalink: /projects/
-title: Software projects
-description: >
- Here is a list of all projects I worked on that I deem good or important
- enough to publish here. This list won't always be complete, but it's good
- enough for a quick overview.
----
-{% assign projects = site.projects | sort: 'title' %}
-
-# Projects
-
-Here is a list of all projects I worked on that I deem good or important enough
-to publish here. This list won't always be complete, but you can check my
-profiles on [GitLab][gitlab] or [Github][github] if you're interested to see
-more.
-
-All of the projects listed below are [Free software][free-software], and are
-made in my free time. Contributions in any form are welcome. This includes, but
-is not limited to, pull/merge requests, bug reports and [financial
-support][support]. You can also come discuss the projects and possible issues
-you have found with them on IRC or contact me through email. Details for both
-can be found [on the homepage][home].
-
-Some projects have extended descriptions available. You can reach these by
-clicking their respective links. You can read some background information on
-why I decided to start out with the project, and how to make use of it yourself
-as well.
-
-<table class="table">
- <thead>
- <tr>
- <th>Project</th>
- <th>Source code repository</th>
- </tr>
- </thead>
- <tbody>
- {% for project in projects %}
- <tr>
- <td>
- {% if project.content != "" %}
- <a href="{{ project.url }}">{{ project.title }}</a>
- {% else %}
- {{ project.title }}
- {% endif %}
- </td>
- <td>
- <a href="{{ project.repo }}">{{ project.repo }}</a>
- </td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-
-[free-software]: https://en.wikipedia.org/wiki/Free_software
-[github]: https://github.com/tyil
-[gitlab]: https://gitlab.com/tyil
-[home]: /
-[support]: /support/
diff --git a/src/_pages/slides.md b/src/_pages/slides.md
deleted file mode 100644
index d03fd41..0000000
--- a/src/_pages/slides.md
+++ /dev/null
@@ -1,64 +0,0 @@
----
-layout: default
-permalink: /slides/
-title: Presentations and Slides
-description: >
- Here is a list of the slides I've used for presentations. The slides are in
- Markdown format, and can be compiled into a working slideshow using
- reveal-md. The slides here are the original sources, and include speaker
- notes.
----
-
-# Presentations and Slides
-Here is the list of presentations I've given and the slideshows I've used for
-them. If there are video sources available, they will be linked to as well.
-
-The slides are written in Markdown, and can be compiled to a usable slideshow
-using [`reveal-md`][reveal-md]. The slide sources are complete, including the
-speaker notes.
-
-I've only given a single presentation right now, but I plan to do more of them
-at various events, such as [FOSDEM][fosdem]. I want to give more presentations
-to get better at presenting people and getting them interested in programming
-languages and aspects that I am also interested in. It's also a great way to
-promote my favourite programming language, [Perl 6][perl6].
-
-<table class="table">
- <thead>
- <tr>
- <th>Event</th>
- <th>Date</th>
- <th>Materials</th>
- </tr>
- </thead>
- <tbody>
- {% for slides in site.slides %}
- <tr>
- <td>{{ slides.event }}</td>
- <td>
- {% assign day = slides.date | date: "%-d" %}
- {% case day %}
- {% when '1' or '21' or '31' %}{{ day }}st
- {% when '2' or '22' %}{{ day }}nd
- {% when '3' or '23' %}{{ day }}rd
- {% else %}
- {{ day }}th
- {% endcase %}
- {{ slides.date | date: "of %B, %Y" }}
- </td>
- <td>
- <a href="https://gitlab.com/tyil/blog/blob/master/{{ slides.path }}">
- Slides
- </a>
- {% if slides.video %}
- , <a href="{{ slides.video }}">Video</a>
- {% endif %}
- </td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-
-[reveal-md]: https://github.com/webpro/reveal-md
-[fosdem]: https://fosdem.org/
-[perl6]: https://perl6.org/
diff --git a/src/_pages/support.md b/src/_pages/support.md
deleted file mode 100644
index d65e0c3..0000000
--- a/src/_pages/support.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-layout: default
-permalink: /support/
-title: Funding me
-description: >
- Thanks for considering to support my work. It's much appreciated, and it
- helps me to spend more time writing articles, tutorials, free software and
- promote more free software.
----
-
-# Supporting me
-Thanks for considering to support my work. It's much appreciated, and it helps me
-to spend more time writing articles, tutorials, free software and promote more
-free software.
-
-I think free software is very important to have around, and all software made
-should be released as free software. As such, I will continue to keep working
-on free software and it's promotion regardless of how much I receive in
-(financial) funding. However, more funding allows me to spend more time on
-this.
-
-## Funding platforms
-I've set up a number of accounts on donation platforms. This way, you can
-decide which platform you trust the most. The platforms I'm available on are:
-
-- [Liberapay](https://liberapay.com/tyil/donate)
-- [MakerSupport](https://www.makersupport.com/tyilanmenyn/pledge)
-- [Patreon](https://www.patreon.com/tyil)
-
-If there are other platforms which you consider to be better, do let me know. I
-am always open to suggestions, and I will try to make time to review other
-platforms if possible. Such suggestions will also be incorporated in [my
-article on Free software funding][article-funding].
-
-## What's it used for?
-Your donations will go towards paying the server I use to work and test things
-on, `hyve2.tyil.net`.
-
-If funding allows, I can look into possibilities to take time off of my day
-time job in order to spend more time on free software work. It would also allow
-me take more time off in order to attend conferences or give presentations on
-my free software projects.
-
-[article-funding]: /articles/funding-yourself-as-free-software-developer/
diff --git a/src/_plugins/admonition_md.rb b/src/_plugins/admonition_md.rb
deleted file mode 100644
index d22cceb..0000000
--- a/src/_plugins/admonition_md.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-module Jekyll
- class AdmonitionMarkdownBlock < Liquid::Block
- @type = ""
-
- def initialize(tag_name, text, tokens)
- super
-
- @type = text
- end
-
- require "redcarpet"
-
- def render(context)
- content = super
-
- '<section class="admonition">
- <div class="admonition-title">' + @type + '</div>
- <div class="admonition-content">
- ' + Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(content) + '
- </div>
- </section>'
- end
- end
-end
-
-Liquid::Template.register_tag('admonition_md', Jekyll::AdmonitionMarkdownBlock)
diff --git a/src/_plugins/highlight.rb b/src/_plugins/highlight.rb
deleted file mode 100644
index d59140c..0000000
--- a/src/_plugins/highlight.rb
+++ /dev/null
@@ -1,127 +0,0 @@
-# frozen_string_literal: true
-
-module Jekyll
- module Tags
- class HighlightBlock < Liquid::Block
- include Liquid::StandardFilters
-
- def initialize(tag_name, markup, tokens)
- super
-
- opts = markup.split
- @opts = Hash.new
- @lang = opts.shift.downcase
-
- opts.each do |opt|
- if opt.include?("=")
- parts = opt.split("=", 2)
-
- @opts[parts[0]] = parts[1]
- end
-
- @opts[opt] = true
- end
- end
-
- def render(context)
- prefix = context["highlighter_prefix"] || ""
- suffix = context["highlighter_suffix"] || ""
- code = super.to_s.gsub(%r!\A(\n|\r)+|(\n|\r)+\z!, "")
-
- is_safe = !!context.registers[:site].safe
-
- output =
- case context.registers[:site].highlighter
- when "pygments"
- render_pygments(code, is_safe)
- when "rouge"
- render_rouge(code)
- else
- render_codehighlighter(code)
- end
-
- rendered_output = add_code_tag(output)
- prefix + rendered_output + suffix
- end
-
- def sanitized_opts(opts, is_safe)
- if is_safe
- Hash[[
- [:startinline, opts.fetch(:startinline, nil)],
- [:hl_lines, opts.fetch(:hl_lines, nil)],
- [:linenos, opts.fetch(:linenos, nil)],
- [:encoding, opts.fetch(:encoding, "utf-8")],
- [:cssclass, opts.fetch(:cssclass, nil)],
- ].reject { |f| f.last.nil? }]
- else
- opts
- end
- end
-
- private
-
- def render_pygments(code, is_safe)
- Jekyll::External.require_with_graceful_fail("pygments") unless defined?(Pygments)
-
- highlighted_code = Pygments.highlight(
- code,
- :lexer => @lang,
- :options => sanitized_opts(@highlight_options, is_safe)
- )
-
- if highlighted_code.nil?
- Jekyll.logger.error <<~MSG
- There was an error highlighting your code:
-
- #{code}
-
- While attempting to convert the above code, Pygments.rb returned an unacceptable value.
- This is usually a timeout problem solved by running `jekyll build` again.
- MSG
- raise ArgumentError, "Pygments.rb returned an unacceptable value "\
- "when attempting to highlight some code."
- end
-
- highlighted_code.sub('<div class="highlight"><pre>', "").sub("</pre></div>", "")
- end
-
- def render_rouge(code)
- require "rouge"
- formatter = ::Rouge::Formatters::HTMLLegacy.new(
- :line_numbers => @highlight_options[:linenos],
- :wrap => false,
- :css_class => "highlight",
- :gutter_class => "gutter",
- :code_class => "code"
- )
- lexer = ::Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
- formatter.format(lexer.lex(code))
- end
-
- def render_codehighlighter(code)
- h(code).strip
- end
-
- def add_code_tag(code)
- code_attributes = [
- "class=\"language-#{@lang.to_s.tr("+", "-")}\"",
- "data-lang=\"#{@lang}\"",
- ].join(" ")
-
- output = "<figure class=\"highlight\"><pre><code #{code_attributes}>"
- output += code.chomp
- output += "</code></pre>"
-
- if @opts["tio"]
- output += "<div class=\"code-link\"><a href=\"#{@opts["tio"]}\" target=\"_blank\">Run this code</a></div>"
- end
-
- output += "</figure>"
-
- output
- end
- end
- end
-end
-
-Liquid::Template.register_tag("highlight", Jekyll::Tags::HighlightBlock)
diff --git a/src/_plugins/html-markdown.rb b/src/_plugins/html-markdown.rb
deleted file mode 100644
index 7d60137..0000000
--- a/src/_plugins/html-markdown.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module Jekyll
- class MarkdownBlock < Liquid::Block
- def initialize(tag_name, text, tokens)
- super
- end
-
- require "redcarpet"
-
- def render(context)
- content = super
-
- "#{Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(content)}"
- end
- end
-end
-
-Liquid::Template.register_tag('markdown', Jekyll::MarkdownBlock)
diff --git a/src/_plugins/jekyll-less.rb b/src/_plugins/jekyll-less.rb
deleted file mode 100644
index 4950c11..0000000
--- a/src/_plugins/jekyll-less.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-##
-#
-# `jekyll-less` is loaded like this to fix a certain bug
-# (https://github.com/zroger/jekyll-less/issues/15).
-#
-##
-require "jekyll-less"
-
-@@mtimes = {}
diff --git a/src/_posts/2018-10-11-hackerrank-solutions-python3-and-perl6-part-2.html b/src/_posts/2018-10-11-hackerrank-solutions-python3-and-perl6-part-2.html
deleted file mode 100644
index 60a9a75..0000000
--- a/src/_posts/2018-10-11-hackerrank-solutions-python3-and-perl6-part-2.html
+++ /dev/null
@@ -1,706 +0,0 @@
----
-title: "Hackerrank solutions: Python 3 and Perl 6 (part 2)"
-layout: language-war
-tags: Hackerrank Perl6 Python Python3 Programming Raku
-description: >
- A number of solutions to Hackerrank challenges in both the Python 3 and the
- Perl 6 programming languages. This is the second part of the series, and will
- work through the subdomain of Strings.
----
-
-{% markdown %}
-# Hackerrank solutions: Python 3 and Perl 6 (part 2)
-{% endmarkdown %}
-
-{% markdown %}
-As a continuation of the [previous
-part](/post/2018/09/13/hackerrank-solutions-python3-and-perl6-part-1/) of this
-series, I will be continuing to work through some Hackerrank challenges for
-Python 3, and compare the solutions to how I would solve them in a language I'm
-more proficient in, Perl 6. In this post, I will work through some of the
-Python 3 string challenges from Hackerrank.
-
-Raiph [posted a comment on
-Reddit](https://www.reddit.com/r/perl6/comments/9ffc2p/hackerrank_solutions_python_3_and_perl_6_part_1/e5xml3m)
-suggesting a slightly different layout, which I will be using for this post.
-Additional comments are always welcome as I try to improve the format.
-{% endmarkdown %}
-
-{% admonition_md Disclaimer %}
-Once again I'd like to make clear I'm trying to stick to the original
-Hackerrank challenges by not using any imports not specifically used in the
-original challenge. If you have suggestions for Python 3 or Perl 6 modules to
-make a given task easier, I still appreciate them, but I won't update my
-solutions to use a module.
-{% endadmonition_md %}
-
-{% markdown %}
-## Challenges
-{% endmarkdown %}
-
-<div class="language-war">
- <div class="language-announcer">
-
-{% markdown %}
-### String Split and Join
-
-This challenge involves a string containing spaces, where the spaces are to be
-replaced with dashes (`-`) instead.
-{% endmarkdown %}
-
- </div>
- <div class="language-arena">
- <div class="language-challenger">
- <div class="language-code">
-
-{% highlight python3 tio=https://tio.run/##K6gsycjPM/7/PyU1TaG4ICezJD4xLyU@Kz8zTyMnMy9V04pLAQiKUktKi/IUlHSV9OBSemDlGkoKSpqa/wuKMvNKNNAMyMwrKC3R0ARKp@XnKyQlFgFxFQA %}
-def split_and_join(line):
- return "-".join(line.split(" "))
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-I personally am not too fond that `join` takes a list of words to join
-together, whereas `split` takes a word to split with. It feels a little
-inconsistent. It also doesn't allow me to read the code logically from left to
-right.
-{% endmarkdown %}
-
- </div>
- </div>
- <div class="language-defender">
- <div class="language-code">
-
-{% highlight perl6 tio=https://tio.run/##K0gtyjH7/7@4NEmhuCAns0Q3MS9FNys/M09BQyUnMy9VU6GaSwEIwBw9sBINJQUlTT2QGg0lXSVNrtr/KlqefnrFOaVFBXpqqKboFSdW/k/Lz1dISiwC4ioA %}
-sub split-and-join ($line) {
- $line.split(" ").join("-")
-}
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-The Perl 6 solution to the challenge does the same as the Python variant. Even
-the function names are the same! The biggest difference is that I can chain the
-functions from left to right, leading to clearer code.
-{% endmarkdown %}
-
- </div>
- </div>
- </div>
- <div class="language-announcer">
-
-{% markdown %}
-### What's Your Name?
-
-The next challenge is a simply string formatting task. You get two inputs, a
-first name and a last name, and have to put it in a string which will be
-printed to `STDOUT`.
-{% endmarkdown %}
-
- </div>
- <div class="language-arena">
- <div class="language-challenger">
- <div class="language-code">
-
-{% highlight python3 tio=https://tio.run/##XYzBCsIwEETv/YqxUEigePHmD@jZm6cSyRYj22ww2UK/PobqyWEOAzPz0laeEk@1epqR3iGWaVbmKbqFjBvxsOcOTXtl@isxC4bcfMBdFC/NBZ54JY@2EKQdeOwx4Pu39R8bYtJi7IhfsPWiwUu3uoib5KzLBw %}
-def print_full_name(a, b):
- print("Hello %s %s! You just delved into python." % (a, b))
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-Before you begin, I know this can be done using `f""` strings, and that was my
-first attempt to use as well. However, Hackerrank did not accept this,
-complaining about invalid syntax, so I assume they're running an older Python 3
-than I do.
-
-That said, this is a simple `printf` formatted string, which then accepts a
-tuple of arguments to put into the string. `printf` formatted string are very
-powerful in their possibilities, and it's clear to read.
-{% endmarkdown %}
-
- </div>
- </div>
- <div class="language-defender">
- <div class="language-code">
-
-{% highlight perl6 tio=https://tio.run/##K0gtyjH7/7@4NEmhoCgzr0Q3rTQnRzcvMTdVQyVRR0ElSVOhmksBCIoTKxWUPFJzcvIVVBKB4ooKkfmlClmlxSUKKak5ZakpCkDd@QoBQPMUzPSUuGr/Y5in5emnl55aAjQVytL875NYVFTJFZ6YkwMA %}
-sub print-full-name($a, $b) {
- say "Hello $a $b! You just delved into Perl 6."
-}
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-Perl 6 has double-quote semantics that many people may be familiar with from
-other languages. When you insert a variable in a double-quoted string, it's
-`.Str` value will be used. That is to say, the value will be converted to a
-`Str` if required, and then put into the string.
-
-If you need it or want it for clarity, you can also use `"Hello {$a}"` in Perl
-6, allowing you to use it similarly to Python 3's `f""` strings.
-{% endmarkdown %}
-
- </div>
- </div>
- </div>
- <div class="language-announcer">
-
-{% markdown %}
-### Mutations
-
-You are given a string _string_, an integer _position_ and a character
-_character_. In _string_, replace the character at _position_ to the given
-_character_. The position is counted from starting point 0, so I don't have to
-think about differences between what a human or computer considers to be
-position 1 in a string.
-{% endmarkdown %}
-
- </div>
- <div class="language-arena">
- <div class="language-challenger">
- <div class="language-code">
-
-{% highlight python3 tio=https://tio.run/##VY5BC8IwDIXv/RVhpxaKIN4Ef4mIjNm5iCYlTQ/79bXrpmIuyeN975E468R0KOUWRnhl7TVckwrS3a7LQ@SEikwehqmXftAg7migzqITnOCJSTfc/YzzJ3ipyDdqGiBBsxB03e7BSLbxrsTaoPb/C6SY1ToPi7WJptbLlZHZ7I28AQ %}
-def mutate_string(string, position, character):
- chars = list(string)
- chars[position] = character
-
- return "".join(chars)
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-This is basically what the example showed as well that came with the challenge,
-so wasn't too hard to solve. My only complaint was that I couldn't call my list
-"list", because that's a reserved keyword.
-{% endmarkdown %}
-
- </div>
- </div>
- <div class="language-defender">
- <div class="language-code">
-
-{% highlight perl6 tio=https://tio.run/##K0gtyjH7/7@4NEkht7QksSRVt7ikKDMvXUFDBcLQUVApyC/OLMnMzwMykzMSixKTS1KLNBWquRSAILdSwSEns7hEwVYBqkEvOT83yRosCZaJhuuPBSmCm2DNhVCjl5WfmWfNVfsfxQ0aKlqefnrpqSVAizFYmnrFiZX/0/LzuQy5igA %}
-sub mutate-string ($string, $position, $character) {
- my @list = $string.comb;
- @list[$position] = $character;
-
- @list.join;
-}
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-The Perl 6 variant does the same things as the Python variant. `comb` without
-arguments converts a string to a list of characters, and `join` without
-arguments joins a list together to a string.
-{% endmarkdown %}
-
- </div>
- </div>
- </div>
- <div class="language-announcer">
-
-{% markdown %}
-### Find a String
-
-In the following challenge you are given a string _string_, and a substring
-_sub\_string_. The challenge is to find how often a substring occurs in the
-_string_. The substrings may overlap one another, so the string `"ABCDCDC"`
-contains the substring `"CDC"` twice.
-{% endmarkdown %}
-
- </div>
- <div class="language-arena">
- <div class="language-challenger">
- <div class="language-code">
-
-{% highlight python3 tio=https://tio.run/##XU67CsMwDNz9FTfaxENKt4CHPv4ilNCHkwqKbBx76Ne7bhxIqYSQdNzp5N/x6Xif88OOuLvEcZjTbY6BeJK1aRRkqLPqBEosRBi0YllHF0AgRrjyZGWr8bK8qtUq@QaNqGBPHaGprO32Bcb8eG26zbIx2FXPYGMKXOHsCz/K//eJfYpSaayDUvlwPJ1LilIf %}
-def count_substring(string, sub_string):
- count = 0
-
- for i in range(0, len(string)):
- if string[i:i + len(sub_string)] == sub_string:
- count += 1
-
- return count
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-As solution to this challenge I loop through the entire _string_, and check
-whether it contains the _sub\_string_ at that point. If it does, I increment
-_count_ by 1. Now, I learned that Python also has the inline `if`, just like
-Perl 6 does, however, it also *needs* an `else` block. That put me off from
-using it in this situation. I think it puts me off from using it in most
-situations, actually. With an `else` coming after it, it just becomes messy to
-read, in my opinion.
-{% endmarkdown %}
-
- </div>
- </div>
- <div class="language-defender">
- <div class="language-code">
-
-{% highlight perl6
-tio=https://tio.run/##K0gtyjH7/7@4NEkhOb80r0QXyCouKcrMS1fQUIEwdBRUgIK6EI6mQjUXZ2pOam6xAlRaoa5OIdcqvwxoUGKBPpJSfa7a/2hmaqhoefrppaeWAM2EsjT1ihMr/zs6ObsAIRcQAwA %}
-sub count-substring ($string, $sub-string) {
- elems $string ~~ m:overlap/$sub-string/
-}
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-The Perl 6 version makes use of some regex magic, and the `elems` subroutine.
-`elems` returns the number of elements in a list, which in this case would be
-the number of matches found by the regex. The `m:overlap//` makes a regex to
-*m*atch, with *overlap*ping strings.
-{% endmarkdown %}
-
- </div>
- </div>
- </div>
- <div class="language-announcer">
-
-{% markdown %}
-### String Validators
-
-In the following challenge, the program is given a string _s_, and have to
-validate a number of properties on this string. These are, in order, whether
-they contain
-
-- alphanumeric characters (a-z, A-Z or 0-9),
-- alphabetic characters (a-z or A-Z),
-- digits (0-9),
-- lowercase characters (a-z),
-- uppercase characters (A-Z).
-
-If any character in the given string passes a validation, it must print
-`"True"`, otherwise it must print `"False"`.
-
-{% endmarkdown %}
-
- </div>
- <div class="language-arena">
- <div class="language-challenger">
- <div class="language-code">
-
-{% highlight python3 tio=https://tio.run/##hZLNioMwEIDvPsXQPdTAIrS9CR72sk@wt1JCVtMaqklIIqWUPrubn6p1MZib38x8zmQi76YW/ND37AwYc9JSjKEoYItxSxjHeJsnYI@GAhiXnUlR4kFZ0/Lq6MN/urMhDe/aTQ7fpNH0853Lmizwil2YWeCNuFG1wDspJ@7xMzRzFso2RJRtERqmTapRPpbZybgwr4aPryZPQHjlazKmPUrfSqYBp/wCflRHk7jWzfhPa1FcG/JXtOGKZlqPYtohf0Ubbnim9SimHfJXtGFBM61HMe2QH7QQvFd6d@/K7zEkZg6lCI3hTAs1vkS3fAvd7l1s@pNUjA@Kow2dUN9//ZbVbn/4@AM %}
-if __name__ == '__main__':
- s = input()
-
- checks = {
- "alnum": False,
- "alpha": False,
- "digit": False,
- "lower": False,
- "upper": False
- }
-
- for char in list(s):
- if not checks["alnum"] and char.isalnum():
- checks["alnum"] = True
-
- if not checks["alpha"] and char.isalpha():
- checks["alpha"] = True
-
- if not checks["digit"] and char.isdigit():
- checks["digit"] = True
-
- if not checks["lower"] and char.islower():
- checks["lower"] = True
-
- if not checks["upper"] and char.isupper():
- checks["upper"] = True
-
- keys = list(checks.keys())
- keys.sort()
-
- for key in keys:
- print(checks[key])
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-As stated in the disclaimer, I don't want to make use of any `import`
-statements unless these are explicitly given in the original challenges. This
-means I can't use regexes, as these are stuffed away in the `re` packages in
-Python. Luckily, Python has the correct check available as a method on the
-string object, so I can still check them in a single line.
-
-I first tried to call the methods on _s_ directly, but this seemed to require
-the entire string to match the check, instead of just any character in the
-string. So I had to loop through the string by character, which I did. If any
-character is found to validate, the appropriate key in the _checks_ dict will
-be set to `True`. Once I've walked through the entire string, I sort the _keys_
-from _checks_ so I can be sure they're printed in the right order.
-{% endmarkdown %}
-
- </div>
- </div>
- <div class="language-defender">
- <div class="language-code">
-
-{% highlight perl6
-tio=https://tio.run/##K0gtyjH7/7@4NEnB19HTT6GaSwEIcisVVIoVbBVUtDz99NJTS6y5wMLFiZUKxfkgqbo6BX2bxJy80lw7fWvscgUZiTjkUjLTM0twyOXkl6cW4ZArLSiAyNX@/@@YlJxiaGSsDAA %}
-sub MAIN {
- my $s = $*IN.get;
-
- say so $s ~~ /<alnum>/;
- say so $s ~~ /<alpha>/;
- say so $s ~~ /<digit>/;
- say so $s ~~ /<lower>/;
- say so $s ~~ /<upper>/;
-}
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-Perl 6 does have regexes available in the main namespace by default, so that
-made this challenge a lot easier to work with. `$*IN` in a special variable
-that refers to `STDIN`, and the `.slurp` method reads all remaining data from
-the buffer.
-
-The next 5 lines all do a `say`, which acts like `print` in Python 3. The `so`
-function coerces a value to become a `Bool`. When a `Bool` is given to `say`,
-it will be coerced to a string representation again, and become either `"True"`
-or `"False"`. The smartmatch operator `~~` has already been covered in the
-previous post, so I recommend you read that as well if you haven't yet.
-
-In Perl 6, regexes are (usually) delimited by the `/` character. The `<alnum>`,
-`<alpha>` etcetera parts are [predefined character classes][classes] in Perl 6
-regexes. These check for exactly what we need in the challenges, so were a good
-pick to solve them.
-
-[classes]: https://docs.perl6.org/language/regexes.html#Predefined_character_classes
-{% endmarkdown %}
-
- </div>
- </div>
- </div>
- <div class="language-announcer">
-
-{% markdown %}
-### Text Wrap
-
-You are given a string _s_ and a width _w_. The string should be split over
-multiple lines so it is never more wide than _w_.
-{% endmarkdown %}
-
- </div>
- <div class="language-arena">
- <div class="language-challenger">
- <div class="language-code">
-
-{% highlight python3 tio=https://tio.run/##K6gsycjPM/7/PzO3IL@oRKEktaKkvCixgIsrJTVNAcTSKC4pysxL11HITayIL89MKcnQtOJSAIKi1JLSojwFpZg8Jb2s/Mw8DZhePRzaNP8XAIVKNMDSmXkFpSUamjoKIBEoBwj@Ozo5u7i6uXt4enn7@Pr5BwQGBYeEhoVHREZxmQIA %}
-import textwrap
-
-def wrap(string, max_width):
- return "\n".join(textwrap.wrap(string, max_width))
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-This challenge introduces the first Python module: `textwrap`. This makes the
-challenge very easy to solve as well, using the `wrap` function exposed by the
-module. This function makes a list of strings, each no longer than the given
-width. I then join these together with newlines to get the desired output.
-{% endmarkdown %}
-
- </div>
- </div>
- <div class="language-defender">
- <div class="language-code">
-
-{% highlight perl6 tio=https://tio.run/##K0gtyjH7/7@4NEmhvCixQEFDpbikKDMvXUdBpTwzpSRDU6GaSwEIoMJ6yfm5SRpQKb2s/Mw8DaWYPCVNrtr/IO0aKlqefnrpqSVA7VCWnmdeiaZecWLlf0cnZxdXN3cPTy9vH18//4DAoOCQ0LDwiMgoLlMA %}
-sub wrap ($string, $width) {
- $string.comb($width).join("\n")
-}
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-For the Perl 6 solution, I have not used an additional module, as all the
-functionality are in the core namespace. I actually made a module in Perl 6 for
-a less primitive wrapping functionality, called [`String::Fold`][string::fold].
-
-In this solution, I use `comb` with the `$width` argument. This returns a list
-of strings, each no longer than the given width, just like Python's
-`textwrap.wrap`. I can then join these together with newlines as well to get
-the same result.
-
-[string::fold]: https://modules.perl6.org/dist/String::Fold:cpan:TYIL
-{% endmarkdown %}
-
- </div>
- </div>
- </div>
- <div class="language-announcer">
-
-{% markdown %}
-### Designer Door Mat
-
-This challenge is more complex than previous challenges. The task at hand is to
-"draw" a certain "design" as the output. For the input, you are given both a
-height _y_ and a width _x_, however _x_ must always be _y_ × 3, so you can
-ignore the second argument.
-
-This one is much simpler to explain using two examples. The first example is
-the output if the input were `7 21`.
-{% endmarkdown %}
-
-{% highlight text %}
----------.|.---------
-------.|..|..|.------
----.|..|..|..|..|.---
--------WELCOME-------
----.|..|..|..|..|.---
-------.|..|..|.------
----------.|.---------
-{% endhighlight %}
-
-{% markdown %}
-In the second example, the input is `11 33`.
-{% endmarkdown %}
-
-{% highlight text %}
----------------.|.---------------
-------------.|..|..|.------------
----------.|..|..|..|..|.---------
-------.|..|..|..|..|..|..|.------
----.|..|..|..|..|..|..|..|..|.---
--------------WELCOME-------------
----.|..|..|..|..|..|..|..|..|.---
-------.|..|..|..|..|..|..|.------
----------.|..|..|..|..|.---------
-------------.|..|..|.------------
----------------.|.---------------
-{% endhighlight %}
-
- </div>
- <div class="language-arena">
- <div class="language-challenger">
- <div class="language-code">
-
-{% highlight python3 tio=https://tio.run/##zZDNS8MwGMbv@SseMwbJlrbrehCEnWS3DS@CBxGpNFsCJQ1p5xD832s@Nh2I7GpyCHmf3/u8H/ZjUJ2pxnFyg@LQu@JNm0Kad9gkEKKk3qsBK2gzMKaNPQyM571ttX/58@KFk6NuBuWJEzpDRVTd7s45p3CGkqPAkhMywWNnERiy6xxabaRH4Wqzl6wUUcHc83cE/pjOvDZ1r2TvLRmL@MwbRctIfKuxYOonA7tI9E3xc/mQYV1A6bQPl2IKRjPqqYQL0PwzD/8fCx@7IHgcY6ubppVxAPLbMRZKSSxoqa8idV5xkfSn9eb@Ybum4gpOUslNd5Tur92FsMBCIPvfuxvHWyzLLw %}
-#! /usr/bin/env python3
-
-height = int((input().split())[0])
-width = height * 3
-half = int((height - 1) / 2)
-
-# Top half
-for line in range(1, half + 1):
- non_dashes = ((line * 2) - 1)
- dashes = int((width - (non_dashes * 3)) / 2)
-
- print("%s%s%s" % ("-" * dashes, ".|." * non_dashes, "-" * dashes))
-
-# Middle line
-print("%s%s%s" % (
- "-" * (int(width / 2) - 3),
- "WELCOME",
- "-" * (int(width / 2) - 3)
-))
-
-# Lower half
-for line in range(half, 0, -1):
- non_dashes = ((line * 2) - 1)
- dashes = int((width - (non_dashes * 3)) / 2)
-
- print("%s%s%s" % ("-" * dashes, ".|." * non_dashes, "-" * dashes))
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-I split the code up in a top half, middle line and lower half, to make it
-easier to reason about. The `for` loops contain some logic to get the right
-output on every line. I found out that `range` supports a third argument,
-allowing me to count down with it as well, which was perfect for this
-situation.
-{% endmarkdown %}
-
- </div>
- </div>
- <div class="language-defender">
- <div class="language-code">
-
-{% highlight perl6 tio=https://tio.run/##zZBBTsMwEEX3PsXgdpEgxVFSqSwiVqiLSi1skFiiIE@xpeBEdtpQhZyDo3CAHix0UpKGSuzxypp5/8/XL9Bm87adXEG4dTZ80SZEs4OCxoy97WGqUL@qEm5her28Fy7b2kJUuZVOKEylWJoy6bhKy1IR9iM4fMLstFFptgkGG68HAoh8OHxBnDA2gce8AALZJrcQCfFLVTM4PvIyuQlk6hS6zuqZzsQ@eSUDM9qfQgXH30hIyfzhNKlcugde84DDey9vai4@RDc4S5sLhiesofBrLWWGkGmDbOzl9QnoFqWc@c3TYnX3sF7U8DfCu0ZWeYX23Il3UYovLO7QOvzX7bTtDcTRNw %}
-#! /usr/bin/env perl6
-
-my $height = $*IN.slurp.words.head.Int;
-my $width = $height × 3;
-my $half-height = ($height - 1) ÷ 2;
-
-# Top half
-for 1..$half-height {
- my $non-dashes = ($_ × 2) - 1;
- my $dashes = ($width - ($non-dashes × 3)) ÷ 2;
-
- say "{"-" x $dashes}{".|." x $non-dashes}{"-" x $dashes}";
-}
-
-# Middle line
-say "{"-" x (($width ÷ 2) - 3)}WELCOME{ "-" x (($width ÷ 2) - 3)}";
-
-# Lower half
-for (1..$half-height).reverse {
- my $non-dashes = ($_ × 2) - 1;
- my $dashes = ($width - ($non-dashes × 3)) ÷ 2;
-
- say "{"-" x $dashes}{".|." x $non-dashes}{"-" x $dashes}";
-}
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-As usual, the code is functionally the same. I must admit I like the functional
-style to get an `Int` from the first argument much more than the way I do it in
-Python, though.
-
-A thing I learned is that the `..` operator that generates a sequence does not
-have a way to make a sequence that counts down, so I had to use `.reverse` on a
-sequence that counts up. I had expected this to Just Work as I expected and
-count down if the left hand side would be larger than the right hand side.
-
-You may notice some fancy Unicode characters in the source, namely `×` for
-multiplication, and ÷ for division. Perl 6 allows Unicode characters in the
-source files, which can oftentimes lead to prettier code. In this particular
-instance, there's no big difference in code readability, though. And for those
-who don't yet have a modern editor that can make Unicode characters, do not
-worry, as the ASCII equivalents (`*` and `/` respectively) still work as well.
-{% endmarkdown %}
-
- </div>
- </div>
- </div>
- <div class="language-announcer">
-
-{% markdown %}
-### String Formatting
-
-In this challenge, you are to produce a table with four columns. The columns
-should contain the decimal, octal, hexadecimal and binary values of the row
-numbers. The function receives an int _number_. The table should contain that
-many rows, starting with row number 1.
-{% endmarkdown %}
-
- </div>
- <div class="language-arena">
- <div class="language-challenger">
- <div class="language-code">
-
-{% highlight python3 tio=https://tio.run/##jZFNCoMwEIX3nmIQhIQG0XYn9CwSTawpJoYYqVJ6dht/W7uQDlll3vveTKJ7W9bqMgyMF6CNUDYtaiOptZwh1cqMG5x44ErSLn0IZku4QsUV8p9Rkr38cJavWuxNYncJAoQCQ9WNo5jA3IcTxAtvLMZzIWnliI72YQkcmnvbWLRl4s1S53Y1JPV/lpJ3dJeUdDtjqzU36ACQCUVNv3iz49DNND0m8oMG1uNDAGgZhMyLkO/hyBKE8fD7EyNKKN1ahF33HL0B %}
-def print_formatted(number):
- max_width = len("{0:b}".format(number))
-
- for i in range(1, number + 1):
- decimal = "{0}".format(i).rjust(max_width)
- octal = "{0:o}".format(i).rjust(max_width)
- hexadecimal = "{0:x}".format(i).upper().rjust(max_width)
- binary = "{0:b}".format(i).rjust(max_width)
-
- print("%s %s %s %s" % (decimal, octal, hexadecimal, binary))
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-In the Python 3 solution I first calculate the max width I need to take into
-account. Then I loop from 1 until _number_ to get the right amount of rows.
-Each iteration, I format the number correctly, and then print it out using a
-printf format string.
-
-The hardest part of this challenge was to get formatting right the way
-Hackerrank wanted it. But I guess that was the entire point of the challenge.
-{% endmarkdown %}
-
- </div>
- </div>
- <div class="language-defender">
- <div class="language-code">
-
-{% highlight perl6 tio=https://tio.run/##XY9NCsIwEIX3PcUQIiRiB1tEBPEA3bhxK0iq0VZMWpIUK1KvXmNb/HurGWbeN29KaS7ztrVVCqXJtQuPhVHCOXkARnWlUmk43APwUjegStThNT@4DFYwjDEVVrKY48YZ3GfC2OV7vYeF1nn0yVsYGd0/jMYSqGuYcTwXuWYECIcHkK0my6BDeDtEiMOhIcZLv2Dskh8Z3U2A7vo8C/6po/lXE3Pe52uCpv17mdFxssaTdJhox9t4@gQ %}
-sub print-formatted ($number) {
- my $max-width = $number.base(2).Str.chars;
- my $format-string = ("%{$max-width}s" xx 4).join(" ") ~ "\n";
-
- for 1..$number {
- $format-string.printf($_, $_.base(8), $_.base(16), $_.base(2));
- }
-}
-{% endhighlight %}
-
- </div>
- <div class="language-commentary">
-
-{% markdown %}
-The Perl 6 solution starts of the same, in that it first calculates the max
-width I need to take into account. Next, however, I generate the format string
-using the `$max-width` to make the `printf` subroutine pad it for me. The `xx`
-operator makes a total of 4 such strings, and puts them into a list, which I
-can then `join` together with a space character, and add a `\n` at the end of
-it (the `~` operator is for string concatenation).
-
-I'm assuming something similar is possible in Python 3 as well, and I would
-like to have an example so I can compare it more fairly.
-
-In the Perl 6 solution I am also able to make use of the `base` method to
-convert the numbers into the right base, something I could not find for Python
-3.
-{% endmarkdown %}
-
- </div>
- </div>
- </div>
-</div>
-
-{% markdown %}
-## Wrap-up
-
-This time I did not do all of the challenges, as the post would probably get
-too long. I still did 8 of them, and might do the rest of the string challenges
-in a later part anyway.
-
-I still find Perl 6 to produce much cleaner code, which is shown best with the
-first challenge. In Perl 6 (`$line.split(" ").join("-")`), I can read from left
-to right to see what I'm doing: I have a `$line`, which I split, and then join.
-In the Python variant (`"-".join(line.split(" "))`), it is much less clear what
-the actual item I'm working on is, as it's hidden inbetween the `join` and
-`split` calls.
-
-Of course, I'm still not an expert on Python 3 code, so I'm sure that there are
-many parts that could be written in a cleaner fashion. I'm still open for
-feedback to improve my Python 3 skills (hence I'm publishing these posts), so
-please let me know if you know better ways to solve some challenges.
-{% endmarkdown %}
diff --git a/src/_projects/assixt.md b/src/_projects/assixt.md
deleted file mode 100644
index 57db5b0..0000000
--- a/src/_projects/assixt.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-layout: project
-title: Assixt
-date: 2017-07-01T00:00:00Z
-langs: Perl 6
-license: GPLv3
-repo: https://gitlab.com/tyil/perl6-app-assixt
----
-
-`assixt`, or `App::Assixt`, is a Perl 6 module which I wrote in order to make
-it easier to write more Perl 6 modules. I also used it as a good project to get
-better with Perl 6 with. Nowadays, it's doing much more than I anticipated at
-the start of the project. I've turned it into a more complete solution for Perl
-6 projects in general.
-
-`assixt` can create new Perl 6 module skeletons, complete with `.gitignore`,
-basic CHANGELOG, Travis and GitLab CI configurations and more. It will also
-keep version numbers used accross your project in sync, create correct
-distribution tarballs and allows you to upload them to [CPAN][cpan] directly
-from the command line.
-
-I've given a presentation on this project at the 14th Dutch Perl Workshop, and
-the slides are available [on the Slides section of my site][slides] as well.
-
-## Installation
-
-To install `assixt`, you will need to have Perl 6 installed, and `zef`
-available as well. I recommend you use [Rakudo Star][rakudo] releases for
-these. If you're using GNU+Linux, you might want to take a look at
-[LoneStar][lonestar]. This is a Bash program that will fetch, unpack and
-compile Rakudo Star Perl 6 for you, including `zef` and a number of other
-common modules.
-
-If you have Perl 6 installed, simply invoke `zef` to install the module
-containing `assixt`:
-
-```sh
-zef install App::Assixt
-```
-
-## Support and feedback
-
-Check out `assixt --help` for an overview of what you can do with it. You can
-also check the README on the repository to get a more extensive overview of the
-possibilities, and some examples on how to use it.
-
-You can also create issues on the repository if you are still having trouble,
-or perhaps even found a bug. The `#perl6` channel on Freenode might also be of
-assistance, as I am almost always available in that channel (so long as I'm
-awake). You can report feedback through issues or IRC as well.
-
-[cpan]: https://www.cpan.org/
-[slides]: /slides/
-[lonestar]: /projects/lonestar/
-[rakudo]: https://rakudo.org/
diff --git a/src/_projects/config.md b/src/_projects/config.md
deleted file mode 100644
index e3af2e9..0000000
--- a/src/_projects/config.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: Config
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/p6-Config
----
diff --git a/src/_projects/dist-helper.md b/src/_projects/dist-helper.md
deleted file mode 100644
index 73cab90..0000000
--- a/src/_projects/dist-helper.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: Dist::Helper
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/perl6-dist-helper
----
diff --git a/src/_projects/io-path-dirstack.md b/src/_projects/io-path-dirstack.md
deleted file mode 100644
index 240b206..0000000
--- a/src/_projects/io-path-dirstack.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: IO::Path::Dirstack
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/perl6-io-path-dirstack
----
diff --git a/src/_projects/irc-client-plugin-github.md b/src/_projects/irc-client-plugin-github.md
deleted file mode 100644
index ef5f6d8..0000000
--- a/src/_projects/irc-client-plugin-github.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: IRC::Client::Plugin::Github
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/perl6-IRC-Client-Plugin-Github
----
diff --git a/src/_projects/irc-client-plugin-ignore.md b/src/_projects/irc-client-plugin-ignore.md
deleted file mode 100644
index ce4fc17..0000000
--- a/src/_projects/irc-client-plugin-ignore.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: IRC::Client::Plugin::Ignore
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/perl6-IRC-Client-Plugin-Ignore
----
diff --git a/src/_projects/irc-client-plugin-nickserv.md b/src/_projects/irc-client-plugin-nickserv.md
deleted file mode 100644
index b9363a5..0000000
--- a/src/_projects/irc-client-plugin-nickserv.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: IRC::Client::Plugin::NickServ
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/perl6-IRC-Client-Plugin-NickServ
----
diff --git a/src/_projects/irc-client-plugin-urltitle.md b/src/_projects/irc-client-plugin-urltitle.md
deleted file mode 100644
index 36a9e83..0000000
--- a/src/_projects/irc-client-plugin-urltitle.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: IRC::Client::Plugin::UrlTitle
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/perl6-IRC-Client-Plugin-UrlTitle
----
diff --git a/src/_projects/lonestar.html b/src/_projects/lonestar.html
deleted file mode 100644
index fd88975..0000000
--- a/src/_projects/lonestar.html
+++ /dev/null
@@ -1,83 +0,0 @@
----
-layout: project
-title: LoneStar
-date: 2018-07-01T00:00:00Z
-langs: Bash
-license: AGPLv3
-repo: https://git.tyil.nl/tyil/lonestar
----
-
-{% markdown %}
-LoneStar is a simple program, written in Bash, to download and install [the
-Rakudo Star Perl 6 distribution](https://rakudo.org). As of the moment of
-writing this program, Rakudo Star Perl 6 binaries cannot easily be moved around
-on the OS, making regular installation methods more troublesome than they ought
-to be. To deal with the installation issue, I wrote LoneStar, to just take care
-of it. I chose to use Bash to ensure it can run on a wide range of GNU+Linux
-systems without much trouble.
-{% endmarkdown %}
-
-{% markdown %}
-## Installation
-
-LoneStar is given a `Makefile` which can take care of installation. However, it
-does not _need_ to be installed if you just want to try it out first. I would
-recommend installation anyway, in order to make easy use of the `init`
-subcommand (which will update you `$PATH` to include the Perl 6 executables for
-you).
-
-You can clone the repo using git, and use `make` to install it:
-{% endmarkdown %}
-
-{% highlight sh %}
-cd "$(mktemp -d)"
-git clone https://gitlab.com/tyil/lonestar .
-make DESTDIR=/usr/local install
-{% endhighlight %}
-
-{% markdown %}
-Some shells will require you to _rehash the $PATH_. On Bash, this is done
-using `hash -r`. Zsh users should run `rehash`. Other shell users may have to
-consult their respective shell's manual. With newer shells, this is oftentimes
-not necessary, though.
-
-## Usage
-
-You can invoke `lonestar` without any parameters to get a list of subcommands
-it will accept, together with optional parameters. To just get the latest
-Rakudo Star Perl 6 distribution installed, use the `install` subcommand.
-{% endmarkdown %}
-
-{% highlight sh %}
-lonestar install
-{% endhighlight %}
-
-{% markdown %}
-Once it has been installed, you can update your `$PATH` with `init`.
-{% endmarkdown %}
-
-{% highlight sh %}
-eval $(lonestar init)
-{% endhighlight %}
-
-{% markdown %}
-This will make sure the directory containing the `perl6` program will be
-searched whenever you want to run a Perl 6 program. It also includes the
-directory that contains all executable modules that have been installed.
-Consequentally, this will make the module installer `zef` available to you.
-
-You can confirm whether Perl 6 works by retrieving the current version.
-{% endmarkdown %}
-
-{% highlight sh %}
-perl6 --version
-{% endhighlight %}
-
-If this command did not fail, you should be good to go!
-
-{% markdown %}
-## Issues and feedback
-
-If you have any issues or feedback on this program, please contact me via any of
-the channels listed on the homepage of my blog.
-{% endmarkdown %}
diff --git a/src/_projects/mpd-client.md b/src/_projects/mpd-client.md
deleted file mode 100644
index eea593c..0000000
--- a/src/_projects/mpd-client.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: MPD::Client
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/p6-MPD-Client
----
diff --git a/src/_projects/musashi.md b/src/_projects/musashi.md
deleted file mode 100644
index e59c8e9..0000000
--- a/src/_projects/musashi.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: Musashi
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://github.com/scriptkitties/musashi
----
diff --git a/src/_projects/pod-to-pager.adoc b/src/_projects/pod-to-pager.adoc
deleted file mode 100644
index ca1af10..0000000
--- a/src/_projects/pod-to-pager.adoc
+++ /dev/null
@@ -1,102 +0,0 @@
----
-layout: project
-title: Pod::To::Pager
-date: 2018-07-15T00:00:00Z
-langs: Perl 6
-license: AGPLv3
-repo: https://gitlab.com/tyil/perl6-pod-to-pager
----
-:toc: preamble
-
-`Pod::To::Pager` is a Perl 6 project to generate prettier output from Perl 6
-Pod structures. By default, Perl 6 ships with a very simple Pod formatter,
-which can be used by calling `perl6 --doc <file>`. You can specify a doc
-formatter by giving it as argument, like `perl6 --doc=Text <file>`. This will
-use the `Pod::To::Text` module to format the output, which is also the default.
-
-But, I wanted something prettier, something I would actually like reading if I
-were looking for documentation on a module. Most people are familiar with UNIX
-man pages (or at least, most people who will read, this I hope). So I wanted to
-create something similar. To get used to Perl 6 Pod, I just tried making simple
-text, with some coloring, as this is easier than also trying to learn how man
-pages are to be created.
-
-And so, `Pod::To::Pager` was born. I've received some feedback from the Perl 6
-community, and included some of it in to the module. It comes with a `p6man`
-utility, which is very much like `p6doc`. It calls the formatter, and calls a
-pager to show the result. It looks very much like the UNIX man pages, and the
-pager lets you read it like one. It's basically an on-the-fly generated man
-page.
-
-== Installation
-
-To install the module, be sure to have Perl 6 and `zef`, the Perl 6 module
-manager, installed on your system. You can then call `zef install` to have it
-download, test, and install the module:
-
-[source,sh]
-----
-zef install Pod::To::Pager
-----
-
-== Usage
-
-Once installed, you can use the module in many ways. You can call it as a Pod
-formatter on Perl 6 itself:
-
-[source,sh]
-----
-perl6 --doc=Pager lib/Some/Module.pm6
-----
-
-This will render the document on `STDOUT`, and display it in your terminal. If
-it doesn't support scrollback, there's a high chance you can't see the top part
-of it. To solve that, you can use a pager, like `less`:
-
-[source,sh]
-----
-perl6 --doc=Pager lib/Some/Module.pm6 | less
-----
-
-This will keep it possible to scroll through the output, until you press `q` to
-quit the pager.
-
-=== p6man
-
-Since the last form is the way it was intended to be used (hence the *pager* in
-`Pod::To::Pager`), there's a utility bundled with the module to make such use
-easier. Inspired by the existence of `p6doc`, it's called `p6man`. It will use
-`less` as the pager on GNU+Linux if possible, otherwise it will fall back to
-`more`. On Windows, it will just use `more`. You can call it with either a
-(relative) file path, or a module name:
-
-[source,sh]
-----
-p6man lib/Some/Module.pm6
-p6man App::Assixt
-----
-
-For the latter variant to work, the module must be installed locally.
-
-=== In Perl 6 programs
-
-You can also use it directly in Perl 6 programs. This allows you to change
-behaviour of the formatting process, or render the program's own documentation
-with this formatter's output. To do that, `use` the module, and call the
-`format` method on the formatter class:
-
-[source,perl6]
-----
-use Pod::To::Pager;
-
-say Pod::To::Pager($=pod);
-----
-
-This will render the program's own Pod structure, formatted using
-`Pod::To::Pager`, and print it to `STDOUT`.
-
-== Feedback
-
-If you have any feedback, please reach out to me on `#perl6` on IRC, or create
-an issue on the repository.
-
diff --git a/src/_projects/scriptkitties-overlay.md b/src/_projects/scriptkitties-overlay.md
deleted file mode 100644
index cede5a6..0000000
--- a/src/_projects/scriptkitties-overlay.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: Scriptkitties Overlay
-date: 2017-01-01T00:00:00Z
-langs: Bash
-license: GPLv2+
-repo: https://c.darenet.org/scriptkitties/overlay
----
diff --git a/src/_projects/string-fold.md b/src/_projects/string-fold.md
deleted file mode 100644
index 60f9cc3..0000000
--- a/src/_projects/string-fold.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: String::Fold
-date: 2017-01-01 00:00:00
-langs: Perl 6
-license: GPLv3
-repo: https://gitlab.com/tyil/perl6-string-fold
----
diff --git a/src/_projects/subbot.md b/src/_projects/subbot.md
deleted file mode 100644
index 79eb26a..0000000
--- a/src/_projects/subbot.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: SubBot
-date: 2017-01-01 00:00:00
-langs: Lua
-license: GPLv2
-repo: https://c.darenet.org/tyil/subbot
----
diff --git a/src/_projects/tachikoma.md b/src/_projects/tachikoma.md
deleted file mode 100644
index beb03d0..0000000
--- a/src/_projects/tachikoma.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: Tachikoma
-date: 2017-01-01 00:00:00
-langs: Ruby
-license: GPLv3
-repo: https://c.darenet.org/scriptkitties/tachikoma
----
-
diff --git a/src/_slides/perl6-using-app-assixt-to-improve-module-development.md b/src/_slides/perl6-using-app-assixt-to-improve-module-development.md
deleted file mode 100644
index b16c979..0000000
--- a/src/_slides/perl6-using-app-assixt-to-improve-module-development.md
+++ /dev/null
@@ -1,244 +0,0 @@
----
-title: "Perl6: Using `App::Assixt` to improve module development"
-event: 14th Dutch Perl Workshop
-date: 2018-07-07
----
-
-# `App::Assixt`
-## Improving module development
-
----
-
-# About me
-
-- Patrick Spek (`TYIL`)
-- https://www.tyil.nl
-- @tyil@mastodon.social
-
-note:
- I have about 10 Perl 6 modules available on CPAN right now. `Config` and
- parser modules, `IRC::Client` plugins, `Hash::Merge`, `Dist::Helper` and
- `App::Assixt`.
-
----
-
-# Why?
-
-- Manually updating JSON is annoying
-- Wanted to ease development
-- Wanted easier way to distribute
-
-note:
- It's my 2nd project in Perl 6, following `Config`.
-
----
-
-# How?
-
-- Uses `Dist::Helper`
-- Updates `META6.json`
-- Creates skeleton files
-
-note:
- `Dist::Helper` is the base that deals with the actual interaction with the
- modules. `App::Assixt` is a CLI frontend with some nice extras to make it
- usable.
-
----
-
-# How do I get it?
-
-```
-$ zef install App::Assixt
-```
-
-note:
- `App::Assixt` is easily available through `CPAN`, and `zef` is able to
- install it cleanly nowadays.
-
----
-
-# Using it
-
-```
-$ assixt help
-```
-
-```
-$ p6man assixt
-```
-
-note:
- - p6man is shipped with `Pod::To::Pager`, still in development!
-
----
-
-# Creating a new project
-
-## Manual
-```
-$ mkdir my-new-perl6-project
-$ cp my-old-project/META6.json my-new-perl6-project/.
-$ $EDITOR my-new-perl6-project/META6.json
-```
-
-## `assixt`
-```
-$ assixt new --name=my-new-perl6-project
-```
-
-note:
- - `assixt new` can also be done without arguments, it will ask for a name
- then
- - additional questions will also be asked to fill out the META6.json
- - `assixt` will add gitlab-ci, travis configuration
- - default changelog
- - gitignore
-
----
-
-# Adding files
-
-## Manual
-```
-$ mkdir -p lib/App/Local
-$ touch lib/App/Local/NewClass.pm6
-$ $EDITOR META6.json
-```
-
-## `assixt`
-```
-$ assixt touch class App::Local::NewClass
-```
-
-- Classes
-- Tests
-- Unit modules
-
----
-
-# Adding a dependency
-
-## Manual
-```
-$ $EDITOR META6.json
-$ zef install Config
-```
-
-## `assixt`
-```
-$ assixt depend Config
-```
-
-note:
- `--no-install` skips the step where `zef` tries to install the module.
-
----
-
-# Bumping the version
-
-## Manual
-```
-$ $EDITOR META6.json
-```
-
-## `assixt`
-```
-$ assixt bump
-```
-
-note:
- - `bump` asks for additional user input to decide whether to bump the patch,
- minor or major level.
- - In a next release, will also update `=VERSION` in pod, and CHANGELOG
- releases.
-
----
-
-# Create a new dist
-
-## Manual
-```
-$ tar czf My-Dist-0.1.2.tar.gz --exclude-vcs-ignores [--exclude...] .
-$ mv !:2 ~/.local/dists/.
-```
-
-## `assixt`
-```
-$ assixt dist
-```
-
----
-
-# Uploading to CPAN
-
-## Manual
-Through your favourite webbrowser
-
-## `assixt`
-```
-$ assixt upload ~/.local/var/assixt/dists/Dist-Helper-0.19.0.tar.gz
-```
-
-note:
- After starting development and testing of `assixt`, I eventually found `mi6`,
- but I stick to `assixt` as it can do much more.
-
----
-
-# `push` shorthand
-
-```
-$ assixt push
-```
-
-- Bump
-- Dist
-- Upload
-
-note:
- Does a `bump`, `dist` and `upload`, one after another.
-
----
-
-# Workflow
-
-```
-$ assixt new Local::App
-$ cd perl6-local-app
-$ assixt depend Config
-$ assixt touch class Local::App::Foo
-$ $EDITOR
-$ assixt push
-```
-
-note:
- Creates a new module directory, make the module depend on `Config`, create a
- class named `Local::App::Foo` and push the module to CPAN.
-
----
-
-# Future plans
-
----
-
-## QA check
-- Will perform QA checks to improve module quality
-- Based on `Release::Checklist` by [Tux]
-- Work In Progress on Github
-
----
-
-## Other ideas
-- `meta`: To update misc dist info, such as the authors
-- `sync-meta`: To synchronize a `META6.json` from an existing module
-- Improve `new`: Also generate a default `README.pod6`
-
-note:
- `sync-meta` is intended to also create a new `META6.json` if none exists
- yet.
-
----
-
-# Questions
-
diff --git a/src/atom.xml b/src/atom.xml
deleted file mode 100644
index 3d77b95..0000000
--- a/src/atom.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/assixt.xml b/src/atom/assixt.xml
deleted file mode 100644
index a8db160..0000000
--- a/src/atom/assixt.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Assixt"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/caldav.xml b/src/atom/caldav.xml
deleted file mode 100644
index 04a0438..0000000
--- a/src/atom/caldav.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "CalDAV"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/carddav.xml b/src/atom/carddav.xml
deleted file mode 100644
index d1839d9..0000000
--- a/src/atom/carddav.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "CardDAV"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/cgit.xml b/src/atom/cgit.xml
deleted file mode 100644
index 4ed7ea2..0000000
--- a/src/atom/cgit.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "cgit"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/cjdns.xml b/src/atom/cjdns.xml
deleted file mode 100644
index b1c6c8f..0000000
--- a/src/atom/cjdns.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "cjdns"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/cloudflare.xml b/src/atom/cloudflare.xml
deleted file mode 100644
index aef0e92..0000000
--- a/src/atom/cloudflare.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Cloudflare"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/codeofconduct.xml b/src/atom/codeofconduct.xml
deleted file mode 100644
index d76b4c3..0000000
--- a/src/atom/codeofconduct.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "CodeOfConduct"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/conference.xml b/src/atom/conference.xml
deleted file mode 100644
index 8911405..0000000
--- a/src/atom/conference.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Conference"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/contributions.xml b/src/atom/contributions.xml
deleted file mode 100644
index 4a057dd..0000000
--- a/src/atom/contributions.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Contributions"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/dkim.xml b/src/atom/dkim.xml
deleted file mode 100644
index 68c5a77..0000000
--- a/src/atom/dkim.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "DKIM"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/docker.xml b/src/atom/docker.xml
deleted file mode 100644
index aea106e..0000000
--- a/src/atom/docker.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Docker"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/dovecot.xml b/src/atom/dovecot.xml
deleted file mode 100644
index 4506b5f..0000000
--- a/src/atom/dovecot.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Dovecot"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/email.xml b/src/atom/email.xml
deleted file mode 100644
index c176c7c..0000000
--- a/src/atom/email.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Email"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/encryption.xml b/src/atom/encryption.xml
deleted file mode 100644
index ef6fc0f..0000000
--- a/src/atom/encryption.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Encryption"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/freebsd.xml b/src/atom/freebsd.xml
deleted file mode 100644
index 93cf9f7..0000000
--- a/src/atom/freebsd.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "FreeBSD"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/freesoftware.xml b/src/atom/freesoftware.xml
deleted file mode 100644
index 06e6ffd..0000000
--- a/src/atom/freesoftware.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "FreeSoftware"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/funding.xml b/src/atom/funding.xml
deleted file mode 100644
index 8e1c423..0000000
--- a/src/atom/funding.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Funding"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/gentoo.xml b/src/atom/gentoo.xml
deleted file mode 100644
index a1810a9..0000000
--- a/src/atom/gentoo.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Gentoo"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/gettingthingsdone.xml b/src/atom/gettingthingsdone.xml
deleted file mode 100644
index 8984499..0000000
--- a/src/atom/gettingthingsdone.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "GettingThingsDone"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/git.xml b/src/atom/git.xml
deleted file mode 100644
index a7576b2..0000000
--- a/src/atom/git.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Git"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/github.xml b/src/atom/github.xml
deleted file mode 100644
index 4566fe3..0000000
--- a/src/atom/github.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Github"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/gnu+linux.xml b/src/atom/gnu+linux.xml
deleted file mode 100644
index 9b45d03..0000000
--- a/src/atom/gnu+linux.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "GNU+Linux"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/gpg.xml b/src/atom/gpg.xml
deleted file mode 100644
index 5a110b7..0000000
--- a/src/atom/gpg.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "GPG"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/gtk.xml b/src/atom/gtk.xml
deleted file mode 100644
index 61ee743..0000000
--- a/src/atom/gtk.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "GTK"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/hackerrank.xml b/src/atom/hackerrank.xml
deleted file mode 100644
index 6364225..0000000
--- a/src/atom/hackerrank.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Hackerrank"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/hacktoberfest.xml b/src/atom/hacktoberfest.xml
deleted file mode 100644
index 7742423..0000000
--- a/src/atom/hacktoberfest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Hacktoberfest"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/imap.xml b/src/atom/imap.xml
deleted file mode 100644
index edafb41..0000000
--- a/src/atom/imap.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "IMAP"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/letsencrypt.xml b/src/atom/letsencrypt.xml
deleted file mode 100644
index f19bbc3..0000000
--- a/src/atom/letsencrypt.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "LetsEncrypt"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/lonestar.xml b/src/atom/lonestar.xml
deleted file mode 100644
index 3f7a80f..0000000
--- a/src/atom/lonestar.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "LoneStar"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/nginx.xml b/src/atom/nginx.xml
deleted file mode 100644
index 61e5c81..0000000
--- a/src/atom/nginx.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Nginx"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/pastebin.xml b/src/atom/pastebin.xml
deleted file mode 100644
index 9e0a973..0000000
--- a/src/atom/pastebin.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Pastebin"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/perl.xml b/src/atom/perl.xml
deleted file mode 100644
index cd6bd91..0000000
--- a/src/atom/perl.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Perl"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/perl6.xml b/src/atom/perl6.xml
deleted file mode 100644
index d9bdf78..0000000
--- a/src/atom/perl6.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Perl6"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/pgp.xml b/src/atom/pgp.xml
deleted file mode 100644
index a57a3c0..0000000
--- a/src/atom/pgp.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "PGP"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/pigeonhole.xml b/src/atom/pigeonhole.xml
deleted file mode 100644
index 8a8263e..0000000
--- a/src/atom/pigeonhole.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Pigeonhole"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/postfix.xml b/src/atom/postfix.xml
deleted file mode 100644
index b55cfeb..0000000
--- a/src/atom/postfix.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Postfix"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/privacy.xml b/src/atom/privacy.xml
deleted file mode 100644
index bb96ad3..0000000
--- a/src/atom/privacy.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Privacy"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/programming.xml b/src/atom/programming.xml
deleted file mode 100644
index 72f5a7e..0000000
--- a/src/atom/programming.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Programming"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/python.xml b/src/atom/python.xml
deleted file mode 100644
index 5f0d350..0000000
--- a/src/atom/python.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Python"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/python3.xml b/src/atom/python3.xml
deleted file mode 100644
index 8567028..0000000
--- a/src/atom/python3.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Python3"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/raku.xml b/src/atom/raku.xml
deleted file mode 100644
index f9fe0c4..0000000
--- a/src/atom/raku.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Raku"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/raspberrypi.xml b/src/atom/raspberrypi.xml
deleted file mode 100644
index d97fa66..0000000
--- a/src/atom/raspberrypi.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "RaspberryPi"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/sasl.xml b/src/atom/sasl.xml
deleted file mode 100644
index 8302ed7..0000000
--- a/src/atom/sasl.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "SASL"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/security.xml b/src/atom/security.xml
deleted file mode 100644
index b269b3d..0000000
--- a/src/atom/security.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Security"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/spamassassin.xml b/src/atom/spamassassin.xml
deleted file mode 100644
index cea4e91..0000000
--- a/src/atom/spamassassin.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "SpamAssassin"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/sparrowdo.xml b/src/atom/sparrowdo.xml
deleted file mode 100644
index 548d5ce..0000000
--- a/src/atom/sparrowdo.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Sparrowdo"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/spf.xml b/src/atom/spf.xml
deleted file mode 100644
index 3f0369f..0000000
--- a/src/atom/spf.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "SPF"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/ssl.xml b/src/atom/ssl.xml
deleted file mode 100644
index d6b99e1..0000000
--- a/src/atom/ssl.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "SSL"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/systemd.xml b/src/atom/systemd.xml
deleted file mode 100644
index bb522be..0000000
--- a/src/atom/systemd.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Systemd"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/tutorial.xml b/src/atom/tutorial.xml
deleted file mode 100644
index 5d8e20b..0000000
--- a/src/atom/tutorial.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Tutorial"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/vpn.xml b/src/atom/vpn.xml
deleted file mode 100644
index 1c41cb0..0000000
--- a/src/atom/vpn.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "VPN"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/wkd.xml b/src/atom/wkd.xml
deleted file mode 100644
index ff1fc74..0000000
--- a/src/atom/wkd.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "WKD"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/atom/yubikey.xml b/src/atom/yubikey.xml
deleted file mode 100644
index 98bcbc9..0000000
--- a/src/atom/yubikey.xml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "YubiKey"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ site.url }}{{ site.baseurl }}/</id>
- <title>{{ site.title | xml_escape }}</title>
- <subtitle>{{ site.description | strip | xml_escape }}</subtitle>
- <updated>{{ site.time | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ site.baseurl | prepend: site.url }}" />
- <link rel="alternate" type="application/rss+xml" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <link rel="self" type="application/atom+xml" href="{{ "/atom.xml" | prepend: site.baseurl | prepend: site.url }}" />
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <generator version="{{ jekyll.version }}">Jekyll</generator>{% for post in documents limit:10 %}
- <entry>
- <id>{{ site.url }}{{ site.baseurl }}{{ post.url }}</id>
- <title>{{ post.title | xml_escape }}</title>
- <author>
- <name>{{ site.author }}</name>
- <email>{{ site.email }}</email>
- </author>
- <updated>{{ post.date | date_to_xmlschema }}</updated>
- <link rel="alternate" type="text/html" href="{{ post.url | prepend: site.baseurl | prepend: site.url }}" />{% if post.description %}
- <summary>{{ post.description | strip | xml_escape }}</summary>{% endif %}
- <content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">
- {{ post.content | strip | xml_escape }}
- </content>{% for tag in post.tags %}
- <category term="{{ tag | xml_escape }}" />{% endfor %}{% for cat in post.categories %}
- <category term="{{ cat | xml_escape }}" />{% endfor %}
- </entry>{% endfor %}
-</feed>
diff --git a/src/css/custom/blockquotes.less b/src/css/custom/blockquotes.less
deleted file mode 100644
index 3984472..0000000
--- a/src/css/custom/blockquotes.less
+++ /dev/null
@@ -1,18 +0,0 @@
-@import "../variables.less";
-
-.quoteblock {
- width: 90%;
- margin: 0 auto;
- border-left: double black;
- padding: 0.5em;
- background-color: @blockBackgroundColor;
-
- blockquote {
- font-style: italic;
- }
-
- div.attribution {
- text-align: right;
- margin-right: 1em;
- }
-}
diff --git a/src/css/custom/helpers.less b/src/css/custom/helpers.less
deleted file mode 100644
index 2c4d80b..0000000
--- a/src/css/custom/helpers.less
+++ /dev/null
@@ -1,5 +0,0 @@
-@import "../variables.less";
-
-.center {
- text-align: center;
-}
diff --git a/src/css/custom/navigation.less b/src/css/custom/navigation.less
deleted file mode 100644
index 9c9ef4e..0000000
--- a/src/css/custom/navigation.less
+++ /dev/null
@@ -1,30 +0,0 @@
-@import "../variables.less";
-
-// Navigation bar
-nav {
- padding-bottom: 8px;
- border-bottom: double @bodyTextColor;
- text-align: center;
- font-family: Sans;
-
- a, a:visited {
- margin: 0 0.5em;
- font-size: 24px;
- text-decoration: none;
- color: @bodyTextColor;
- }
-
- .brand-name {
- text-align: center;
- display: block;
- font-weight: bold;
- font-size: 32px;
- color: @bodyTextColor;
- margin-bottom: 8px;
- }
-}
-
-// Generic links
-a, a:visited {
- color: @linkColor;
-}
diff --git a/src/css/formats/asciidoc.less b/src/css/formats/asciidoc.less
deleted file mode 100644
index 89dfcb2..0000000
--- a/src/css/formats/asciidoc.less
+++ /dev/null
@@ -1,45 +0,0 @@
-@import "../variables.less";
-
-.toc {
- font-weight: bold;
-
- ul {
- font-weight: normal;
- list-style-type: decimal;
- }
-}
-
-.admonitionblock {
- background-color: @blockBackgroundColor;
- border: 1px solid @blockBorderColor;
- margin: 0.5em auto 1.75em auto;
- width: 90%;
- padding: 0.5em;
-
- table {
- td.icon {
- text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
- font-size: 1.5em;
-
- div.title {
- margin: 0 1em;
- }
- }
-
- td.content {
- padding: 0 1.125em;
- border-left: 1px solid #ddd;
- }
- }
-}
-
-div#footnotes {
- font-size: smaller;
-
- hr {
- margin-top: 2em;
- width: 80%;
- text-align: left;
- color: @blockBorderColor;
- }
-}
diff --git a/src/css/language-war.less b/src/css/language-war.less
deleted file mode 100644
index c7f563b..0000000
--- a/src/css/language-war.less
+++ /dev/null
@@ -1,69 +0,0 @@
-@import "./variables.less";
-
-main {
- max-width: 80em;
- margin: 0 auto;
- text-align: justify;
-
- @media(max-width: @mainWidth) {
- padding: 1rem;
- }
-
- h1, h2, p {
- max-width: @mainWidth;
- margin-left: auto;
- margin-right: auto;
- }
-
- .language-announcer {
- max-width: @mainWidth;
- margin: 0 auto;
- }
-
- .admonitionblock {
- max-width: @mainWidth * .9;
- margin: 0 auto;
- }
-
- figure.highlight pre {
- overflow-x: auto;
- }
-
- @media(min-width: @mainWidth) {
- .language-arena {
- display: grid;
-
- grid-template-columns: [challenger] 1fr [defender] 1fr [end];
- grid-template-rows: [code] auto [comments] auto [end];
-
- .language-challenger {
- grid-column-start: challenger;
- grid-column-end: defender;
- grid-row-start: code;
- grid-row-end: end;
- }
-
- .language-defender {
- grid-column-start: defender;
- grid-column-end: end;
- grid-row-start: code;
- grid-row-end: end;
- }
-
- .language-code {
- grid-row-start: code;
- grid-row-end: comments;
-
- max-width: 40em;
- }
-
- .language-commentary {
- max-width: @mainWidth;
- grid-row-start: comments;
- grid-row-end: end;
-
- margin: 0 40px;
- }
- }
- }
-}
diff --git a/src/css/main.less b/src/css/main.less
deleted file mode 100644
index bb22e74..0000000
--- a/src/css/main.less
+++ /dev/null
@@ -1,144 +0,0 @@
-@import "./variables.less";
-
-@import "./custom/blockquotes.less";
-@import "./custom/helpers.less";
-@import "./custom/navigation.less";
-
-@import "./formats/asciidoc.less";
-
-html {
- background-color: @bodyBackgroundColor;
-}
-
-body {
- color: @bodyTextColor;
- font-size: 16px;
- line-height: 1.4;
- text-align: justify;
- width: 100%;
- margin: 0;
-}
-
-small {
- font-size: 0.7em;
-}
-
-li p {
- margin: 0;
-}
-
-table {
- width: 100%;
-}
-
-a.image-link {
- text-decoration: none;
-}
-
-span.footer-link-seperator {
- margin: .5rem;
- overflow: hidden;
-}
-
-figure.highlight, pre.highlight {
- border: 2px solid @blockBorderColor;
- background-color: @blockBackgroundColor;
- overflow-x: auto;
-
- pre, pre.pygments {
- margin: 0;
- padding: 6px 6px;
- }
-
- .code-link {
- border-top: 1px dotted @blockBorderColor;
- padding: 3px 8px;
- text-align: right;
- }
-}
-
-code {
- padding: 2px;
-}
-
-pre code {
- padding: 0;
-}
-
-div.container {
- max-width: @mainWidth;
- margin: 0 auto 0.5em auto;
- padding: 1em 2em 0 2em;
-}
-
-span.citneed{
- vertical-align: top;
- font-size: 0.7em;
- padding-left: 0.3em;
-}
-
-p.text-center {
- text-align: center;
-}
-
-article {
- footer hr {
- width: 50%
- }
-}
-
-section.admonition {
- background-color: #f6f6f6;
- border: 1px solid #d7d7d7;
- margin: .5rem auto 1.74rem auto;
- width: 85%;
- max-width: @mainWidth * .9;
- padding: 1.5rem;
-
- .admonition-title {
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 1.5rem;
- text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
- }
-
- p {
- margin: 0;
- }
-}
-
-@media(min-width: @mainWidth) {
- section.admonition {
- display: grid;
-
- grid-template-columns: [title] .25fr [body] 1fr [end];
-
- .admonition-title {
- grid-column-start: title;
- grid-column-end: body;
- }
-
- p {
- grid-column-start: body;
- grid-column-end: end;
-
- padding-left: 10px;
- border-left: 1px solid #ddd;
- }
- }
-}
-
-@media(max-width: @mainWidth) {
- section.admonition {
- .admonition-title {
- text-align: center;
- margin-top: 0;
- }
-
- p {
- padding-top: 10px;
- border-top: 1px solid #ddd;
- }
- }
-}
diff --git a/src/css/pygments.scss b/src/css/pygments.scss
deleted file mode 100644
index 8c1f06d..0000000
--- a/src/css/pygments.scss
+++ /dev/null
@@ -1,74 +0,0 @@
----
----
-.listingblock .pygments, .highlight pre {
- background: #f8f8f8;
-
- .hll { background-color: #ffffcc }
- .c, .tok-c { color: #008800; font-style: italic } /* Comment */
- .err, .tok-err { border: 1px solid #FF0000 } /* Error */
- .k, .tok-k { color: #AA22FF; font-weight: bold } /* Keyword */
- .o, .tok-o { color: #666666 } /* Operator */
- .ch, .tok-ch { color: #008800; font-style: italic } /* Comment.Hashbang */
- .cm, .tok-cm { color: #008800; font-style: italic } /* Comment.Multiline */
- .cp, .tok-cp { color: #008800 } /* Comment.Preproc */
- .cpf, .tok-cpf { color: #008800; font-style: italic } /* Comment.PreprocFile */
- .c1, .tok-c1 { color: #008800; font-style: italic } /* Comment.Single */
- .cs, .tok-cs { color: #008800; font-weight: bold } /* Comment.Special */
- .gd, .tok-gd { color: #A00000 } /* Generic.Deleted */
- .ge, .tok-ge { font-style: italic } /* Generic.Emph */
- .gr, .tok-gr { color: #FF0000 } /* Generic.Error */
- .gh, .tok-gh { color: #000080; font-weight: bold } /* Generic.Heading */
- .gi, .tok-gi { color: #00A000 } /* Generic.Inserted */
- .go, .tok-go { color: #888888 } /* Generic.Output */
- .gp, .tok-gp { color: #000080; font-weight: bold } /* Generic.Prompt */
- .gs, .tok-gs { font-weight: bold } /* Generic.Strong */
- .gu, .tok-gu { color: #800080; font-weight: bold } /* Generic.Subheading */
- .gt, .tok-gt { color: #0044DD } /* Generic.Traceback */
- .kc, .tok-kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */
- .kd, .tok-kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */
- .kn, .tok-kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */
- .kp, .tok-kp { color: #AA22FF } /* Keyword.Pseudo */
- .kr, .tok-kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */
- .kt, .tok-kt { color: #00BB00; font-weight: bold } /* Keyword.Type */
- .m, .tok-m { color: #666666 } /* Literal.Number */
- .s, .tok-s { color: #BB4444 } /* Literal.String */
- .na, .tok-na { color: #BB4444 } /* Name.Attribute */
- .nb, .tok-nb { color: #AA22FF } /* Name.Builtin */
- .nc, .tok-nc { color: #0000FF } /* Name.Class */
- .no, .tok-no { color: #880000 } /* Name.Constant */
- .nd, .tok-nd { color: #AA22FF } /* Name.Decorator */
- .ni, .tok-ni { color: #999999; font-weight: bold } /* Name.Entity */
- .ne, .tok-ne { color: #D2413A; font-weight: bold } /* Name.Exception */
- .nf, .tok-nf { color: #00A000 } /* Name.Function */
- .nl, .tok-nl { color: #A0A000 } /* Name.Label */
- .nn, .tok-nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
- .nt, .tok-nt { color: #008000; font-weight: bold } /* Name.Tag */
- .nv, .tok-nv { color: #B8860B } /* Name.Variable */
- .ow, .tok-ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
- .w, .tok-w { color: #bbbbbb } /* Text.Whitespace */
- .mb, .tok-mb { color: #666666 } /* Literal.Number.Bin */
- .mf, .tok-mf { color: #666666 } /* Literal.Number.Float */
- .mh, .tok-mh { color: #666666 } /* Literal.Number.Hex */
- .mi, .tok-mi { color: #666666 } /* Literal.Number.Integer */
- .mo, .tok-mo { color: #666666 } /* Literal.Number.Oct */
- .sa, .tok-sa { color: #BB4444 } /* Literal.String.Affix */
- .sb, .tok-sb { color: #BB4444 } /* Literal.String.Backtick */
- .sc, .tok-sc { color: #BB4444 } /* Literal.String.Char */
- .dl, .tok-dl { color: #BB4444 } /* Literal.String.Delimiter */
- .sd, .tok-sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */
- .s2, .tok-s2 { color: #BB4444 } /* Literal.String.Double */
- .se, .tok-se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
- .sh, .tok-sh { color: #BB4444 } /* Literal.String.Heredoc */
- .si, .tok-si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
- .sx, .tok-sx { color: #008000 } /* Literal.String.Other */
- .sr, .tok-sr { color: #BB6688 } /* Literal.String.Regex */
- .s1, .tok-s1 { color: #BB4444 } /* Literal.String.Single */
- .ss, .tok-ss { color: #B8860B } /* Literal.String.Symbol */
- .bp, .tok-bp { color: #AA22FF } /* Name.Builtin.Pseudo */
- .fm, .tok-fm { color: #00A000 } /* Name.Function.Magic */
- .vc, .tok-vc { color: #B8860B } /* Name.Variable.Class */
- .vg, .tok-vg { color: #B8860B } /* Name.Variable.Global */
- .vi, .tok-vi { color: #B8860B } /* Name.Variable.Instance */
- .vm, .tok-vm { color: #B8860B } /* Name.Variable.Magic */
- .il, .tok-il { color: #666666 } /* Literal.Number.Integer.Long */
-}
diff --git a/src/css/variables.less b/src/css/variables.less
deleted file mode 100644
index 9441283..0000000
--- a/src/css/variables.less
+++ /dev/null
@@ -1,14 +0,0 @@
-// Main site colors
-@bodyBackgroundColor: #fefefe;
-@bodyTextColor: #454545;
-
-// Link Colors
-@linkColor: #07a;
-@linkVisitedInvertedColor: #ac5a82;
-
-// Special blocks
-@blockBackgroundColor: #f6f6f6;
-@blockBorderColor: #d7d7d7;
-
-// Sizes
-@mainWidth: 900px;
diff --git a/src/favicon.ico b/src/favicon.ico
deleted file mode 100644
index e69de29..0000000
--- a/src/favicon.ico
+++ /dev/null
diff --git a/src/feed.xml b/src/feed.xml
deleted file mode 100644
index b1687d1..0000000
--- a/src/feed.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | sort: 'date' | reverse %}<?xml version="1.0" encoding="utf-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/assixt.xml b/src/feed/assixt.xml
deleted file mode 100644
index 07a93a7..0000000
--- a/src/feed/assixt.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Assixt"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/caldav.xml b/src/feed/caldav.xml
deleted file mode 100644
index 8175dfc..0000000
--- a/src/feed/caldav.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "CalDAV"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/carddav.xml b/src/feed/carddav.xml
deleted file mode 100644
index 056d2de..0000000
--- a/src/feed/carddav.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "CardDAV"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/cgit.xml b/src/feed/cgit.xml
deleted file mode 100644
index 3a74168..0000000
--- a/src/feed/cgit.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "cgit"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/cjdns.xml b/src/feed/cjdns.xml
deleted file mode 100644
index 67e4f56..0000000
--- a/src/feed/cjdns.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "cjdns"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/cloudflare.xml b/src/feed/cloudflare.xml
deleted file mode 100644
index cea82c2..0000000
--- a/src/feed/cloudflare.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Cloudflare"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/codeofconduct.xml b/src/feed/codeofconduct.xml
deleted file mode 100644
index 109fea3..0000000
--- a/src/feed/codeofconduct.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "CodeOfConduct"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/conference.xml b/src/feed/conference.xml
deleted file mode 100644
index 8e95305..0000000
--- a/src/feed/conference.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Conference"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/contributions.xml b/src/feed/contributions.xml
deleted file mode 100644
index 8dfbb5e..0000000
--- a/src/feed/contributions.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Contributions"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/dkim.xml b/src/feed/dkim.xml
deleted file mode 100644
index 17df93d..0000000
--- a/src/feed/dkim.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "DKIM"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/docker.xml b/src/feed/docker.xml
deleted file mode 100644
index b85ccda..0000000
--- a/src/feed/docker.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Docker"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/dovecot.xml b/src/feed/dovecot.xml
deleted file mode 100644
index 58aa52a..0000000
--- a/src/feed/dovecot.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Dovecot"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/email.xml b/src/feed/email.xml
deleted file mode 100644
index 7fe9b58..0000000
--- a/src/feed/email.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Email"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/encryption.xml b/src/feed/encryption.xml
deleted file mode 100644
index f3ea900..0000000
--- a/src/feed/encryption.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Encryption"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/freebsd.xml b/src/feed/freebsd.xml
deleted file mode 100644
index 069f233..0000000
--- a/src/feed/freebsd.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "FreeBSD"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/freesoftware.xml b/src/feed/freesoftware.xml
deleted file mode 100644
index c32b2c2..0000000
--- a/src/feed/freesoftware.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "FreeSoftware"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/funding.xml b/src/feed/funding.xml
deleted file mode 100644
index 3c05888..0000000
--- a/src/feed/funding.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Funding"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/gentoo.xml b/src/feed/gentoo.xml
deleted file mode 100644
index b251074..0000000
--- a/src/feed/gentoo.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Gentoo"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/gettingthingsdone.xml b/src/feed/gettingthingsdone.xml
deleted file mode 100644
index 2770fb1..0000000
--- a/src/feed/gettingthingsdone.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "GettingThingsDone"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/git.xml b/src/feed/git.xml
deleted file mode 100644
index a7a1b7c..0000000
--- a/src/feed/git.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Git"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/github.xml b/src/feed/github.xml
deleted file mode 100644
index 6a0712b..0000000
--- a/src/feed/github.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Github"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/gnu+linux.xml b/src/feed/gnu+linux.xml
deleted file mode 100644
index b809c0f..0000000
--- a/src/feed/gnu+linux.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "GNU+Linux"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/gpg.xml b/src/feed/gpg.xml
deleted file mode 100644
index e7e8fb0..0000000
--- a/src/feed/gpg.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "GPG"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/gtk.xml b/src/feed/gtk.xml
deleted file mode 100644
index 0b53794..0000000
--- a/src/feed/gtk.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "GTK"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/hackerrank.xml b/src/feed/hackerrank.xml
deleted file mode 100644
index aea4f09..0000000
--- a/src/feed/hackerrank.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Hackerrank"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/hacktoberfest.xml b/src/feed/hacktoberfest.xml
deleted file mode 100644
index 1b5cd6e..0000000
--- a/src/feed/hacktoberfest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Hacktoberfest"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/imap.xml b/src/feed/imap.xml
deleted file mode 100644
index 9139ea1..0000000
--- a/src/feed/imap.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "IMAP"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/letsencrypt.xml b/src/feed/letsencrypt.xml
deleted file mode 100644
index ee243c1..0000000
--- a/src/feed/letsencrypt.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "LetsEncrypt"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/lonestar.xml b/src/feed/lonestar.xml
deleted file mode 100644
index 96a4ce8..0000000
--- a/src/feed/lonestar.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "LoneStar"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/nginx.xml b/src/feed/nginx.xml
deleted file mode 100644
index 1ee1261..0000000
--- a/src/feed/nginx.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Nginx"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/pastebin.xml b/src/feed/pastebin.xml
deleted file mode 100644
index 9522530..0000000
--- a/src/feed/pastebin.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Pastebin"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/perl.xml b/src/feed/perl.xml
deleted file mode 100644
index 2eb9693..0000000
--- a/src/feed/perl.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Perl"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/perl6.xml b/src/feed/perl6.xml
deleted file mode 100644
index 3d608bd..0000000
--- a/src/feed/perl6.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Perl6"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/pgp.xml b/src/feed/pgp.xml
deleted file mode 100644
index 4616637..0000000
--- a/src/feed/pgp.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "PGP"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/pigeonhole.xml b/src/feed/pigeonhole.xml
deleted file mode 100644
index 39e8a5b..0000000
--- a/src/feed/pigeonhole.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Pigeonhole"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/postfix.xml b/src/feed/postfix.xml
deleted file mode 100644
index b7190ac..0000000
--- a/src/feed/postfix.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Postfix"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/privacy.xml b/src/feed/privacy.xml
deleted file mode 100644
index 4c9055c..0000000
--- a/src/feed/privacy.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Privacy"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/programming.xml b/src/feed/programming.xml
deleted file mode 100644
index 5370b9a..0000000
--- a/src/feed/programming.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Programming"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/python.xml b/src/feed/python.xml
deleted file mode 100644
index a611e24..0000000
--- a/src/feed/python.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Python"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/python3.xml b/src/feed/python3.xml
deleted file mode 100644
index 7a3ffb7..0000000
--- a/src/feed/python3.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Python3"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/raku.xml b/src/feed/raku.xml
deleted file mode 100644
index 4f288ee..0000000
--- a/src/feed/raku.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Raku"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/raspberrypi.xml b/src/feed/raspberrypi.xml
deleted file mode 100644
index cdc7792..0000000
--- a/src/feed/raspberrypi.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "RaspberryPi"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/sasl.xml b/src/feed/sasl.xml
deleted file mode 100644
index bfcaffe..0000000
--- a/src/feed/sasl.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "SASL"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/security.xml b/src/feed/security.xml
deleted file mode 100644
index 5836628..0000000
--- a/src/feed/security.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Security"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/spamassassin.xml b/src/feed/spamassassin.xml
deleted file mode 100644
index 0e2681e..0000000
--- a/src/feed/spamassassin.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "SpamAssassin"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/sparrowdo.xml b/src/feed/sparrowdo.xml
deleted file mode 100644
index 0b97ddb..0000000
--- a/src/feed/sparrowdo.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Sparrowdo"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/spf.xml b/src/feed/spf.xml
deleted file mode 100644
index 8b8c609..0000000
--- a/src/feed/spf.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "SPF"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/ssl.xml b/src/feed/ssl.xml
deleted file mode 100644
index 39c559a..0000000
--- a/src/feed/ssl.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "SSL"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/systemd.xml b/src/feed/systemd.xml
deleted file mode 100644
index 08619e5..0000000
--- a/src/feed/systemd.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Systemd"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/tutorial.xml b/src/feed/tutorial.xml
deleted file mode 100644
index a2806be..0000000
--- a/src/feed/tutorial.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "Tutorial"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/vpn.xml b/src/feed/vpn.xml
deleted file mode 100644
index 0a05cf1..0000000
--- a/src/feed/vpn.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "VPN"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/wkd.xml b/src/feed/wkd.xml
deleted file mode 100644
index 056a265..0000000
--- a/src/feed/wkd.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "WKD"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/feed/yubikey.xml b/src/feed/yubikey.xml
deleted file mode 100644
index a2f0553..0000000
--- a/src/feed/yubikey.xml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: null
----
-{% assign documents = site.documents | where: 'feed', true | where_exp: 'post', 'post.tags contains "YubiKey"' | sort: 'date' | reverse %}<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ site.title }}</title>
- <description>{{ site.description | strip | xml_escape }}</description>
- <link>{{ site.baseurl | prepend: site.url }}</link>
- <language>en</language>
- <managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
- <webMaster>{{ site.email }} ({{ site.author }})</webMaster>
- <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
- <docs>http://www.feedvalidator.org/docs/rss2.html</docs>
- <ttl>1440</ttl>
- <generator>Jekyll v{{ jekyll.version }}</generator>
- <atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />{% for post in documents limit:10 %}
- <item>
- <title>{{ post.title }}</title>
- <guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
- <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
- <link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>{% if post.description %}
- <description>{{ post.description | strip | xml_escape }}</description>{% endif %}
- <author>{{ site.email }} ({{ site.author }})</author>{% for tag in post.tags %}
- <category>{{ tag | xml_escape }}</category>{% endfor %}{% for cat in post.categories %}
- <category>{{ cat | xml_escape }}</category>{% endfor %}
- </item>{% endfor %}
- </channel>
-</rss>
diff --git a/src/robots.txt b/src/robots.txt
deleted file mode 100644
index 05ea17f..0000000
--- a/src/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
----
----
-Sitemap: {{ site.url }}/sitemap.xml
diff --git a/static/css/highlight-emacs.css b/static/css/highlight-emacs.css
new file mode 100644
index 0000000..a72faa8
--- /dev/null
+++ b/static/css/highlight-emacs.css
@@ -0,0 +1,82 @@
+/* Background */ .chroma { background-color: #f8f8f8 }
+/* Other */ .chroma .x { }
+/* Error */ .chroma .err { }
+/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
+/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; }
+/* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #ffffcc }
+/* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
+/* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
+/* Keyword */ .chroma .k { color: #aa22ff; font-weight: bold }
+/* KeywordConstant */ .chroma .kc { color: #aa22ff; font-weight: bold }
+/* KeywordDeclaration */ .chroma .kd { color: #aa22ff; font-weight: bold }
+/* KeywordNamespace */ .chroma .kn { color: #aa22ff; font-weight: bold }
+/* KeywordPseudo */ .chroma .kp { color: #aa22ff }
+/* KeywordReserved */ .chroma .kr { color: #aa22ff; font-weight: bold }
+/* KeywordType */ .chroma .kt { color: #00bb00; font-weight: bold }
+/* Name */ .chroma .n { }
+/* NameAttribute */ .chroma .na { color: #bb4444 }
+/* NameBuiltin */ .chroma .nb { color: #aa22ff }
+/* NameBuiltinPseudo */ .chroma .bp { }
+/* NameClass */ .chroma .nc { color: #0000ff }
+/* NameConstant */ .chroma .no { color: #880000 }
+/* NameDecorator */ .chroma .nd { color: #aa22ff }
+/* NameEntity */ .chroma .ni { color: #999999; font-weight: bold }
+/* NameException */ .chroma .ne { color: #d2413a; font-weight: bold }
+/* NameFunction */ .chroma .nf { color: #00a000 }
+/* NameFunctionMagic */ .chroma .fm { }
+/* NameLabel */ .chroma .nl { color: #a0a000 }
+/* NameNamespace */ .chroma .nn { color: #0000ff; font-weight: bold }
+/* NameOther */ .chroma .nx { }
+/* NameProperty */ .chroma .py { }
+/* NameTag */ .chroma .nt { color: #008000; font-weight: bold }
+/* NameVariable */ .chroma .nv { color: #b8860b }
+/* NameVariableClass */ .chroma .vc { }
+/* NameVariableGlobal */ .chroma .vg { }
+/* NameVariableInstance */ .chroma .vi { }
+/* NameVariableMagic */ .chroma .vm { }
+/* Literal */ .chroma .l { }
+/* LiteralDate */ .chroma .ld { }
+/* LiteralString */ .chroma .s { color: #bb4444 }
+/* LiteralStringAffix */ .chroma .sa { color: #bb4444 }
+/* LiteralStringBacktick */ .chroma .sb { color: #bb4444 }
+/* LiteralStringChar */ .chroma .sc { color: #bb4444 }
+/* LiteralStringDelimiter */ .chroma .dl { color: #bb4444 }
+/* LiteralStringDoc */ .chroma .sd { color: #bb4444; font-style: italic }
+/* LiteralStringDouble */ .chroma .s2 { color: #bb4444 }
+/* LiteralStringEscape */ .chroma .se { color: #bb6622; font-weight: bold }
+/* LiteralStringHeredoc */ .chroma .sh { color: #bb4444 }
+/* LiteralStringInterpol */ .chroma .si { color: #bb6688; font-weight: bold }
+/* LiteralStringOther */ .chroma .sx { color: #008000 }
+/* LiteralStringRegex */ .chroma .sr { color: #bb6688 }
+/* LiteralStringSingle */ .chroma .s1 { color: #bb4444 }
+/* LiteralStringSymbol */ .chroma .ss { color: #b8860b }
+/* LiteralNumber */ .chroma .m { color: #666666 }
+/* LiteralNumberBin */ .chroma .mb { color: #666666 }
+/* LiteralNumberFloat */ .chroma .mf { color: #666666 }
+/* LiteralNumberHex */ .chroma .mh { color: #666666 }
+/* LiteralNumberInteger */ .chroma .mi { color: #666666 }
+/* LiteralNumberIntegerLong */ .chroma .il { color: #666666 }
+/* LiteralNumberOct */ .chroma .mo { color: #666666 }
+/* Operator */ .chroma .o { color: #666666 }
+/* OperatorWord */ .chroma .ow { color: #aa22ff; font-weight: bold }
+/* Punctuation */ .chroma .p { }
+/* Comment */ .chroma .c { color: #008800; font-style: italic }
+/* CommentHashbang */ .chroma .ch { color: #008800; font-style: italic }
+/* CommentMultiline */ .chroma .cm { color: #008800; font-style: italic }
+/* CommentSingle */ .chroma .c1 { color: #008800; font-style: italic }
+/* CommentSpecial */ .chroma .cs { color: #008800; font-weight: bold }
+/* CommentPreproc */ .chroma .cp { color: #008800 }
+/* CommentPreprocFile */ .chroma .cpf { color: #008800 }
+/* Generic */ .chroma .g { }
+/* GenericDeleted */ .chroma .gd { color: #a00000 }
+/* GenericEmph */ .chroma .ge { font-style: italic }
+/* GenericError */ .chroma .gr { color: #ff0000 }
+/* GenericHeading */ .chroma .gh { color: #000080; font-weight: bold }
+/* GenericInserted */ .chroma .gi { color: #00a000 }
+/* GenericOutput */ .chroma .go { color: #888888 }
+/* GenericPrompt */ .chroma .gp { color: #000080; font-weight: bold }
+/* GenericStrong */ .chroma .gs { font-weight: bold }
+/* GenericSubheading */ .chroma .gu { color: #800080; font-weight: bold }
+/* GenericTraceback */ .chroma .gt { color: #0044dd }
+/* GenericUnderline */ .chroma .gl { text-decoration: underline }
+/* TextWhitespace */ .chroma .w { color: #bbbbbb }
diff --git a/static/css/highlight-monokai.css b/static/css/highlight-monokai.css
new file mode 100644
index 0000000..1262441
--- /dev/null
+++ b/static/css/highlight-monokai.css
@@ -0,0 +1,82 @@
+/* Background */ .chroma { color: #f8f8f2; background-color: #272822 }
+/* Other */ .chroma .x { }
+/* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
+/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
+/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; }
+/* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #ffffcc }
+/* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
+/* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
+/* Keyword */ .chroma .k { color: #66d9ef }
+/* KeywordConstant */ .chroma .kc { color: #66d9ef }
+/* KeywordDeclaration */ .chroma .kd { color: #66d9ef }
+/* KeywordNamespace */ .chroma .kn { color: #f92672 }
+/* KeywordPseudo */ .chroma .kp { color: #66d9ef }
+/* KeywordReserved */ .chroma .kr { color: #66d9ef }
+/* KeywordType */ .chroma .kt { color: #66d9ef }
+/* Name */ .chroma .n { }
+/* NameAttribute */ .chroma .na { color: #a6e22e }
+/* NameBuiltin */ .chroma .nb { }
+/* NameBuiltinPseudo */ .chroma .bp { }
+/* NameClass */ .chroma .nc { color: #a6e22e }
+/* NameConstant */ .chroma .no { color: #66d9ef }
+/* NameDecorator */ .chroma .nd { color: #a6e22e }
+/* NameEntity */ .chroma .ni { }
+/* NameException */ .chroma .ne { color: #a6e22e }
+/* NameFunction */ .chroma .nf { color: #a6e22e }
+/* NameFunctionMagic */ .chroma .fm { }
+/* NameLabel */ .chroma .nl { }
+/* NameNamespace */ .chroma .nn { }
+/* NameOther */ .chroma .nx { color: #a6e22e }
+/* NameProperty */ .chroma .py { }
+/* NameTag */ .chroma .nt { color: #f92672 }
+/* NameVariable */ .chroma .nv { }
+/* NameVariableClass */ .chroma .vc { }
+/* NameVariableGlobal */ .chroma .vg { }
+/* NameVariableInstance */ .chroma .vi { }
+/* NameVariableMagic */ .chroma .vm { }
+/* Literal */ .chroma .l { color: #ae81ff }
+/* LiteralDate */ .chroma .ld { color: #e6db74 }
+/* LiteralString */ .chroma .s { color: #e6db74 }
+/* LiteralStringAffix */ .chroma .sa { color: #e6db74 }
+/* LiteralStringBacktick */ .chroma .sb { color: #e6db74 }
+/* LiteralStringChar */ .chroma .sc { color: #e6db74 }
+/* LiteralStringDelimiter */ .chroma .dl { color: #e6db74 }
+/* LiteralStringDoc */ .chroma .sd { color: #e6db74 }
+/* LiteralStringDouble */ .chroma .s2 { color: #e6db74 }
+/* LiteralStringEscape */ .chroma .se { color: #ae81ff }
+/* LiteralStringHeredoc */ .chroma .sh { color: #e6db74 }
+/* LiteralStringInterpol */ .chroma .si { color: #e6db74 }
+/* LiteralStringOther */ .chroma .sx { color: #e6db74 }
+/* LiteralStringRegex */ .chroma .sr { color: #e6db74 }
+/* LiteralStringSingle */ .chroma .s1 { color: #e6db74 }
+/* LiteralStringSymbol */ .chroma .ss { color: #e6db74 }
+/* LiteralNumber */ .chroma .m { color: #ae81ff }
+/* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
+/* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
+/* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
+/* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
+/* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
+/* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
+/* Operator */ .chroma .o { color: #f92672 }
+/* OperatorWord */ .chroma .ow { color: #f92672 }
+/* Punctuation */ .chroma .p { }
+/* Comment */ .chroma .c { color: #75715e }
+/* CommentHashbang */ .chroma .ch { color: #75715e }
+/* CommentMultiline */ .chroma .cm { color: #75715e }
+/* CommentSingle */ .chroma .c1 { color: #75715e }
+/* CommentSpecial */ .chroma .cs { color: #75715e }
+/* CommentPreproc */ .chroma .cp { color: #75715e }
+/* CommentPreprocFile */ .chroma .cpf { color: #75715e }
+/* Generic */ .chroma .g { }
+/* GenericDeleted */ .chroma .gd { color: #f92672 }
+/* GenericEmph */ .chroma .ge { font-style: italic }
+/* GenericError */ .chroma .gr { }
+/* GenericHeading */ .chroma .gh { }
+/* GenericInserted */ .chroma .gi { color: #a6e22e }
+/* GenericOutput */ .chroma .go { }
+/* GenericPrompt */ .chroma .gp { }
+/* GenericStrong */ .chroma .gs { font-weight: bold }
+/* GenericSubheading */ .chroma .gu { color: #75715e }
+/* GenericTraceback */ .chroma .gt { }
+/* GenericUnderline */ .chroma .gl { }
+/* TextWhitespace */ .chroma .w { }
diff --git a/src/img/cc-by-sa.png b/static/img/cc-by-sa.png
index 5d64b4a..5d64b4a 100644
--- a/src/img/cc-by-sa.png
+++ b/static/img/cc-by-sa.png
Binary files differ
diff --git a/src/img/email.png b/static/img/email.png
index 2e27f0b..2e27f0b 100644
--- a/src/img/email.png
+++ b/static/img/email.png
Binary files differ
diff --git a/src/img/mastodon.png b/static/img/mastodon.png
index 37dbcef..37dbcef 100644
--- a/src/img/mastodon.png
+++ b/static/img/mastodon.png
Binary files differ
diff --git a/static/js/cookbook.js b/static/js/cookbook.js
new file mode 100644
index 0000000..fc2177c
--- /dev/null
+++ b/static/js/cookbook.js
@@ -0,0 +1,34 @@
+"use strict";
+
+// Kindly copied from MartijnBraam's fathub sources
+// https://sr.ht/~martijnbraam/fathub.org/
+
+var serve_fraction = 1.0;
+
+function update_ingredient_list() {
+ var ingredients = document.querySelectorAll('td[data-amount]');
+ for (var i = 0; i < ingredients.length; i++) {
+ var ingredient = ingredients[i];
+ ingredient.innerText = ingredient.dataset.amount * serve_fraction;
+ }
+}
+
+function adjust_serves() {
+ serve_fraction = this.value / this.dataset.original;
+ update_ingredient_list();
+}
+
+function add_dynamic_controls() {
+ var serves = document.querySelector("td[data-serves]");
+ var spinner = document.createElement('INPUT');
+ spinner.type = 'number';
+ spinner.dataset.original = serves.dataset.serves;
+ spinner.value = serves.dataset.serves;
+ spinner.addEventListener('change', adjust_serves);
+ serves.innerHTML = '';
+ serves.appendChild(spinner);
+}
+
+document.addEventListener("DOMContentLoaded", function () {
+ add_dynamic_controls();
+});
diff --git a/src/pubkey.txt b/static/pubkey.txt
index 77e614f..77e614f 100644
--- a/src/pubkey.txt
+++ b/static/pubkey.txt