From 0af5df93f8c977b2373fab78cea93491d0e18f62 Mon Sep 17 00:00:00 2001 From: speedie Date: Fri, 30 Jun 2023 23:39:01 +0200 Subject: [PATCH] Move blog posts over to using Markdown --- 404.php | 21 + ...need to stop promoting nonfree software.md | 55 + ...to stop promoting nonfree software.md.date | 1 + ... to stop promoting nonfree software.md.num | 1 + ...with Gentoo, now Arch is my best friend.md | 39 + ...Gentoo, now Arch is my best friend.md.date | 1 + ... Gentoo, now Arch is my best friend.md.num | 1 + articles/Host your own services NOW.md | 108 + articles/Host your own services NOW.md.date | 1 + articles/Host your own services NOW.md.num | 1 + ... back to Microsoft Windows.. here's why.md | 91 + ... to Microsoft Windows.. here's why.md.date | 1 + ...k to Microsoft Windows.. here's why.md.num | 1 + .../Important site update (and the Matrix).md | 33 + ...rtant site update (and the Matrix).md.date | 1 + ...ortant site update (and the Matrix).md.num | 1 + .../Important update regarding the site.md | 28 + ...mportant update regarding the site.md.date | 1 + ...Important update regarding the site.md.num | 1 + articles/Normies are destroying GNU+Linux.md | 128 ++ .../Normies are destroying GNU+Linux.md.date | 1 + .../Normies are destroying GNU+Linux.md.num | 1 + .../Swedish man rants about licenses again.md | 75 + ...ish man rants about licenses again.md.date | 1 + ...dish man rants about licenses again.md.num | 1 + articles/The Wayland experience.md | 160 ++ articles/The Wayland experience.md.date | 1 + articles/The Wayland experience.md.num | 1 + ...omium: The best browser for most people.md | 73 + ...: The best browser for most people.md.date | 1 + ...m: The best browser for most people.md.num | 1 + ...se Wayland (and how it can be improved).md | 143 ++ ...yland (and how it can be improved).md.date | 1 + ...ayland (and how it can be improved).md.num | 1 + articles/Why most blogs suck.md | 35 + articles/Why most blogs suck.md.date | 1 + articles/Why most blogs suck.md.num | 1 + articles/Yet another update post.md | 57 + articles/Yet another update post.md.date | 1 + articles/Yet another update post.md.num | 1 + ...ou don't need to justify your decisions.md | 41 + ...n't need to justify your decisions.md.date | 1 + ...on't need to justify your decisions.md.num | 1 + articles/post01.php | 33 - articles/post02.php | 21 - articles/post03.php | 34 - articles/post04.php | 35 - articles/post05.php | 28 - articles/post06.php | 36 - articles/post07.php | 27 - articles/post08.php | 29 - articles/post09.php | 34 - articles/post10.php | 31 - articles/post11.php | 29 - articles/post12.php | 30 - articles/post13.php | 28 - articles/post14.php | 32 - articles/post15.php | 33 - articles/post16.php | 26 - articles/post17.php | 25 - articles/post18.php | 30 - articles/post19.php | 37 - articles/post20.php | 29 - articles/post21.php | 36 - articles/post22.php | 30 - articles/post23.php | 37 - articles/post24.php | 26 - articles/post25.php | 34 - articles/post26.php | 28 - articles/post27.php | 31 - articles/post28.php | 28 - articles/post29.php | 32 - articles/post30.php | 28 - articles/post31.php | 41 - articles/post32.php | 54 - articles/post33.php | 53 - articles/post34.php | 46 - articles/post35.php | 35 - articles/post36.php | 49 - articles/post37.php | 54 - articles/post38.php | 56 - articles/post39.php | 29 - articles/post40.php | 38 - articles/post41.php | 28 - articles/post42.php | 27 - articles/post43.php | 27 - articles/post44.php | 26 - articles/post45.php | 35 - articles/post46.php | 34 - articles/post47.php | 60 - articles/post48.php | 28 - articles/post49.php | 27 - articles/post50.php | 32 - articles/post51.php | 27 - articles/post52.php | 26 - articles/post53.php | 39 - articles/post54.php | 24 - articles/post55.php | 28 - articles/post56.php | 49 - articles/post57.php | 29 - articles/post58.php | 28 - articles/post59.php | 29 - articles/post60.php | 33 - articles/post61.php | 35 - articles/post62.php | 27 - articles/post63.php | 30 - blog.php | 400 +++- md/Markdown.inc.php | 10 + md/Markdown.php | 1909 +++++++++++++++++ md/MarkdownExtra.inc.php | 11 + md/MarkdownExtra.php | 1895 ++++++++++++++++ md/MarkdownInterface.inc.php | 9 + md/MarkdownInterface.php | 38 + php/404.php | 21 + php/blog-p.php | 25 + 115 files changed, 5328 insertions(+), 2205 deletions(-) create mode 100644 404.php create mode 100644 articles/Distros need to stop promoting nonfree software.md create mode 100644 articles/Distros need to stop promoting nonfree software.md.date create mode 100644 articles/Distros need to stop promoting nonfree software.md.num create mode 100644 articles/Friendship ended with Gentoo, now Arch is my best friend.md create mode 100644 articles/Friendship ended with Gentoo, now Arch is my best friend.md.date create mode 100644 articles/Friendship ended with Gentoo, now Arch is my best friend.md.num create mode 100644 articles/Host your own services NOW.md create mode 100644 articles/Host your own services NOW.md.date create mode 100644 articles/Host your own services NOW.md.num create mode 100644 articles/I switched back to Microsoft Windows.. here's why.md create mode 100644 articles/I switched back to Microsoft Windows.. here's why.md.date create mode 100644 articles/I switched back to Microsoft Windows.. here's why.md.num create mode 100644 articles/Important site update (and the Matrix).md create mode 100644 articles/Important site update (and the Matrix).md.date create mode 100644 articles/Important site update (and the Matrix).md.num create mode 100644 articles/Important update regarding the site.md create mode 100644 articles/Important update regarding the site.md.date create mode 100644 articles/Important update regarding the site.md.num create mode 100644 articles/Normies are destroying GNU+Linux.md create mode 100644 articles/Normies are destroying GNU+Linux.md.date create mode 100644 articles/Normies are destroying GNU+Linux.md.num create mode 100644 articles/Swedish man rants about licenses again.md create mode 100644 articles/Swedish man rants about licenses again.md.date create mode 100644 articles/Swedish man rants about licenses again.md.num create mode 100644 articles/The Wayland experience.md create mode 100644 articles/The Wayland experience.md.date create mode 100644 articles/The Wayland experience.md.num create mode 100644 articles/Ungoogled Chromium: The best browser for most people.md create mode 100644 articles/Ungoogled Chromium: The best browser for most people.md.date create mode 100644 articles/Ungoogled Chromium: The best browser for most people.md.num create mode 100644 articles/Why I don't use Wayland (and how it can be improved).md create mode 100644 articles/Why I don't use Wayland (and how it can be improved).md.date create mode 100644 articles/Why I don't use Wayland (and how it can be improved).md.num create mode 100644 articles/Why most blogs suck.md create mode 100644 articles/Why most blogs suck.md.date create mode 100644 articles/Why most blogs suck.md.num create mode 100644 articles/Yet another update post.md create mode 100644 articles/Yet another update post.md.date create mode 100644 articles/Yet another update post.md.num create mode 100644 articles/You don't need to justify your decisions.md create mode 100644 articles/You don't need to justify your decisions.md.date create mode 100644 articles/You don't need to justify your decisions.md.num delete mode 100644 articles/post01.php delete mode 100644 articles/post02.php delete mode 100644 articles/post03.php delete mode 100644 articles/post04.php delete mode 100644 articles/post05.php delete mode 100644 articles/post06.php delete mode 100644 articles/post07.php delete mode 100644 articles/post08.php delete mode 100644 articles/post09.php delete mode 100644 articles/post10.php delete mode 100644 articles/post11.php delete mode 100644 articles/post12.php delete mode 100644 articles/post13.php delete mode 100644 articles/post14.php delete mode 100644 articles/post15.php delete mode 100644 articles/post16.php delete mode 100644 articles/post17.php delete mode 100644 articles/post18.php delete mode 100644 articles/post19.php delete mode 100644 articles/post20.php delete mode 100644 articles/post21.php delete mode 100644 articles/post22.php delete mode 100644 articles/post23.php delete mode 100644 articles/post24.php delete mode 100644 articles/post25.php delete mode 100644 articles/post26.php delete mode 100644 articles/post27.php delete mode 100644 articles/post28.php delete mode 100644 articles/post29.php delete mode 100644 articles/post30.php delete mode 100644 articles/post31.php delete mode 100644 articles/post32.php delete mode 100644 articles/post33.php delete mode 100644 articles/post34.php delete mode 100644 articles/post35.php delete mode 100644 articles/post36.php delete mode 100644 articles/post37.php delete mode 100644 articles/post38.php delete mode 100644 articles/post39.php delete mode 100644 articles/post40.php delete mode 100644 articles/post41.php delete mode 100644 articles/post42.php delete mode 100644 articles/post43.php delete mode 100644 articles/post44.php delete mode 100644 articles/post45.php delete mode 100644 articles/post46.php delete mode 100644 articles/post47.php delete mode 100644 articles/post48.php delete mode 100644 articles/post49.php delete mode 100644 articles/post50.php delete mode 100644 articles/post51.php delete mode 100644 articles/post52.php delete mode 100644 articles/post53.php delete mode 100644 articles/post54.php delete mode 100644 articles/post55.php delete mode 100644 articles/post56.php delete mode 100644 articles/post57.php delete mode 100644 articles/post58.php delete mode 100644 articles/post59.php delete mode 100644 articles/post60.php delete mode 100644 articles/post61.php delete mode 100644 articles/post62.php delete mode 100644 articles/post63.php create mode 100755 md/Markdown.inc.php create mode 100755 md/Markdown.php create mode 100755 md/MarkdownExtra.inc.php create mode 100755 md/MarkdownExtra.php create mode 100755 md/MarkdownInterface.inc.php create mode 100755 md/MarkdownInterface.php create mode 100644 php/404.php create mode 100644 php/blog-p.php diff --git a/404.php b/404.php new file mode 100644 index 0000000..c97a210 --- /dev/null +++ b/404.php @@ -0,0 +1,21 @@ + + + + + + + + +Page not found + + +
+

The page you requested was not found. It's possible that it was deleted, moved, or never existed in the first place. If you're unsure, you might want to check the wiki commit history.

+ +
+ + diff --git a/articles/Distros need to stop promoting nonfree software.md b/articles/Distros need to stop promoting nonfree software.md new file mode 100644 index 0000000..d38603e --- /dev/null +++ b/articles/Distros need to stop promoting nonfree software.md @@ -0,0 +1,55 @@ +# Distros need to stop promoting nonfree software + +2023-06-22 + +It is no secret that I can't stand the absolute state of the modern +GNU/Linux desktop. Even putting all of that aside though, there are +some other issues I want to talk about. I've talked a lot about +package management, audio and more, but the biggest problem is how +we (the community) approach the normies. Many of these easy +distributions come with a graphical package manager. Fair enough if +you're new, right? These package managers often have a "featured" +section, I know PopOS has one, and that's where the problem lies. +PopOS and likely other distributions are actively recommending +nonfree software through the "featured" section. + +That is a huge problem because by recommending nonfree software you are telling +normies that they SHOULD continue to use nonfree software, and they should not +adapt to our ideas and start using free software alternatives. I get that some +nonfree software just does not have good free software replacements, but you +as the distro maintainer need to be able to put your foot down, and stop +recommending Google Chrome or Microsoft Office or LastPass or other nonfree +software when there are clear free software alternatives that usually +accomplish the same task, and usually does a better job at it too. + +The solution: Nonfree software should not be recommended by the GNU/Linux +community. There is no harm in keeping it available, if not intentionally +making it a little bit harder to install, because some users just are not able +to move away from it for many different reasons. But we should not make it as +easy to install nonfree software as it is to install free software. When you +install GNU/Linux, you should be encouraged to move away from nonfree software +for the most part in favor of free software that respects the user's +freedom and privacy. By recommending nonfree software, you are encouraging the +user not to care about privacy, and use GNU/Linux +because "it works better than Windows" rather than "I care about my privacy and security". + +If you have read ploum.net's excellent article titled +[We need more of Richard Stallman, not less](https://ploum.net/2023-06-19-more-rms.html) +you're no doubt aware of this already, but the free software foundation has +slowly been replaced by the more corporate friendly open source movement which +doesn't care about your freedom, only the collaboration aspect of free software. +These same people want Stallman and the Free Software Foundation gone, because +they actively dislike free software. The thing is we NEED Stallman's extremist +views on software. We need to go all out on free software, not just use SOME +free software but mostly nonfree software, because if we don't we still have +terribly privacy and security. And when a "faster" or "better" version of the +free software comes out, why shouldn't we just use that instead? + +The best way to spread free software and avoid spreading nonfree software is to promote +free software, and shame nonfree software for not respecting users' freedom and +privacy. Normies usually get into free software by using GNU/Linux, so there's an +excellent opportunity to promote free software rather than nonfree software. + +Let me know what you think. Do you think it's justified to promote nonfree software? +Do you think we should be even more strict, maybe not even allow nonfree +software in the main repositories? I'm interested to hear about it. Have a good day. diff --git a/articles/Distros need to stop promoting nonfree software.md.date b/articles/Distros need to stop promoting nonfree software.md.date new file mode 100644 index 0000000..5bbb44f --- /dev/null +++ b/articles/Distros need to stop promoting nonfree software.md.date @@ -0,0 +1 @@ +2023-06-22 diff --git a/articles/Distros need to stop promoting nonfree software.md.num b/articles/Distros need to stop promoting nonfree software.md.num new file mode 100644 index 0000000..a8fa06e --- /dev/null +++ b/articles/Distros need to stop promoting nonfree software.md.num @@ -0,0 +1 @@ +62 diff --git a/articles/Friendship ended with Gentoo, now Arch is my best friend.md b/articles/Friendship ended with Gentoo, now Arch is my best friend.md new file mode 100644 index 0000000..26b8501 --- /dev/null +++ b/articles/Friendship ended with Gentoo, now Arch is my best friend.md @@ -0,0 +1,39 @@ +# Friendship ended with Gentoo, now Arch is my best friend + +Alright so I have a brief announcement or something today and that +is, I have officially stopped using Gentoo. Yes that's right, the Gentoo elitist +is now an Arch cuck. But why, why would you commit such a crime you might say? +Well, Gentoo has actually been giving me more and more problems for months now, +and it doesn't seem to get any better. + +I've had so many dumb issues with Gentoo recently, such as Xft fonts being +broken, packages failing to emerge, `--depclean` removing my entire system, +and the final straw, gnome-keyring issues that just do not occur on +other GNU/Linux distributions. In case you're not aware, I have been using +Arch on my laptop for months now, and while Arch has some annoying issues +such as GPG keys constantly breaking pacman when updating, I find that it +works much better now. + +To make matters worse for Gentoo, syncing the repositories takes a very +long time, and it's valuable time that I do not want to spend just because a +program is slow and written in Python. Moving over to Arch was not difficult +though. I said 'fuck it' yesterday at around 04:00 in the morning, and +started installing Arch over Gentoo. Thankfully, as you guys know I have +an arch repository containing nearly the same programs as my Gentoo +repository (overlay), and as such I was able to install my config files +and all my programs using one command. It's super nice, otherwise I +would've probably spent much more time on this. + +Anyways, as for my overlay, I will probably update it every once in a +while using maybe a docker container, but I'm going to be focusing on +the arch repository because it's what I'm using. For those of you +that actually use Arch, this might be good news for you because it means +you will always be able to install my software using pacman. I know +that some of you will probably be disappointed about this, because I'm +kind of known as a Gentoo user at this point, but I just can't take +Portage's stupidity anymore. If you need to however, feel free to remove +my feed! + +I also took the time to move /home to a separate partition, +which is really nice if you want to reinstall quickly. Whatever, that's +all I needed to say with this blog post. Have a good day! diff --git a/articles/Friendship ended with Gentoo, now Arch is my best friend.md.date b/articles/Friendship ended with Gentoo, now Arch is my best friend.md.date new file mode 100644 index 0000000..9b70804 --- /dev/null +++ b/articles/Friendship ended with Gentoo, now Arch is my best friend.md.date @@ -0,0 +1 @@ +2023-03-26 diff --git a/articles/Friendship ended with Gentoo, now Arch is my best friend.md.num b/articles/Friendship ended with Gentoo, now Arch is my best friend.md.num new file mode 100644 index 0000000..0691f67 --- /dev/null +++ b/articles/Friendship ended with Gentoo, now Arch is my best friend.md.num @@ -0,0 +1 @@ +52 diff --git a/articles/Host your own services NOW.md b/articles/Host your own services NOW.md new file mode 100644 index 0000000..db62cdd --- /dev/null +++ b/articles/Host your own services NOW.md @@ -0,0 +1,108 @@ +# Host your own services NOW + +2023-06-24 + +I talk a lot about freedom, privacy and free software on this blog, but today +I want to talk about hosting your own services. But why should you host your +own services? Isn't that really scary and difficult? Doesn't it require very +powerful hardware? No, not really and I'm going to talk about some of +the benefits here. + +Alright so let's talk a bit about why you should host your own stuff and what +you can host. There are many different services you can host. I'm hosting my +website, some files, a Git server, wiki, email server and might host more in +the future. But there are many cool things you can host, such as a Matrix +homeserver, IRC network, SearX instance, PeerTube, NextCloud, it goes on +and on. I won't be talking much about the specific services you can host today. +But why should you host all of this stuff? Why not just use Gmail, or a +public SearX instance, or GitHub, or any of these public services? + +It's because as the sysadmin, you are very powerful and have a lot of power +over your users and your services, and my site and services are no exception. +You have power over everyone that uses your site and services. The ability to +delete their accounts, look at what they're doing, all of these different +things that you have no control over. When you host your own services though, +the only one who is going to be able to see what you upload to your server is +you (and your VPS provider if you're hosting using a VPS). Maybe other people +can see it if they manage to compromise your server or you let your web server +serve content that you don't want public. But in general, you're the only one +who is going to be able to see that. + +Let's take a public SearX instance for example. Let's say you visit +searx.speedie.site and use it as your primary engine. Now, this search engine +does not exist because I host my SearX instance locally but anyways, if you visit +my SearX instance and use it to search for things, I have the power to log the +search queries you search for, and I have the ability to see all the anime pornography +you search for with great shame. Do you really trust me to not look at your +search queries? No? So why should you trust any other SearX instance or hell, +even Google for that matter. For this reason, you should take matters into your +own hands and host your own services that you have control over. That way, +you have the power to customize anything and everything about the service you're +hosting, shut it down at any time to perform maintainence, set up logging, +shred all logs and log absolutely nothing, etc. + +But, doesn't hosting your own services require spending a lot of money? Doesn't +it require a very powerful computer? No. If you want to host many, massive big +files on a VPS or server that you rent, you may not have that much disk space. +But even if that's the case you can host from home on a cheap old Dell Optiplex +or maybe even a Raspberry Pi and just connect storage to it. I'm hosting a Git +server using Gitea, and all the repositories Gitea handles combined only takes +up approximately 870MB. And my public folder where I host downloads to all my +software only takes up about 30MB. That really isn't much, and you can host +that and much, much more on a cheap VPS. And the spmenu wiki I host takes up +31MB. So unless you want to host many, massive files I think making the +argument that you don't have space is ridiculous. Any desktop computer +from.. say 2008 or later is going to be able to handle hosting your site, +and the terrible hard drive it has is going to be able to hold all of +your files as well. + +You can get a cheap VPS from Vultr for $3.50, and you can get a domain for +usually very cheap as well. I went with Namecheap for my domain name, and they +seem quite reliable and not very expensive. If you want to get a VPS from +Vultr, feel free to use [my referral link](https://www.vultr.com/?ref=9327892). +There are other VPS companies though, and I still recommend hosting from home +if you are able to, and your ISP reliably allows you to because it's likely still +going to be a bit cheaper, but more importantly means you avoid the ability for +your VPS provider to look at the contents of the virtual hard disk, and you are +able to use more disk space. You have a lot more freedom that way. Still, a VPS +is not a bad choice if you just want to host a few services and your personal +site, but it's probably not the best option if you want to host NextCloud or a +lot of big files or use it as a media server or anything like that. It also +makes a lot more sense if you want to, for instance set up a VPN. Doing that +on your own network doesn't make much sense unless you use the VPN away from home. + +I won't get into hosting from home as that isn't something I'm familiar +with (although I might try it at some point), and I also won't get into more +complex setups or containers, just the basics. While I'm not a particularly big +fan of Debian based GNU/Linux distributions, simply because of their old +packages and the apt-get package manager, it's a fairly good choice if you want +things to just work and serve your content all day every day. Despite not really +liking Debian very much, it's what this website is hosted on, along with my +other services I have. + +When I'm using a VPS, I usually start by adding a new user and giving him a +password. Then I usually install doas because it's smaller and has had fewer +vulnerabilities than the more bloated sudo that people use. Then I will copy +over my SSH keys to that user's `.ssh` directory. Finally, I **always** disable +authentication using passwords for SSH, and more importantly I disable SSH as the +root user. I do this because the root user is present on almost every machine, meaning +if you want to gain access to someone's server by bruteforcing, a safe bet is to +try to gain access using the root account. Then for extra security I will disable +the actual root user, so the only way to gain superuser is to use `doas` +Now you may have to open ports to be able to host anything on it. If you want to +host websites you will have to open TCP port 80 for HTTP and 443 for HTTPS. On +Vultr VPSes this is done using the `ufw` command, which is the firewall the VPS +comes with. It should be noted though, that if you want to host an email server +you will need to open port 25 used for SMTP, and should be done with the `ufw` +command as well, but you also need to file a ticket on Vultr's website giving +a valid reason for wanting the port to be opened. Usually they will accept your +request, though. + +Now that you've opened the ports you need, you can start hosting the services you +wish to host. I would probably install Apache and php-fpm for PHP to get my +website set up now. A VPS is going to function exactly like any GNU/Linux computer +you're used to, although it will not have a graphical environment. Therefore you +should expect to get familiar with Vim, it is your best friend. Anyways, you should +host your own services, instead of using public services because it's more +private, more secure, and you have much more control than with a public service +that many people are going to use. diff --git a/articles/Host your own services NOW.md.date b/articles/Host your own services NOW.md.date new file mode 100644 index 0000000..4d08007 --- /dev/null +++ b/articles/Host your own services NOW.md.date @@ -0,0 +1 @@ +2023-06-24 diff --git a/articles/Host your own services NOW.md.num b/articles/Host your own services NOW.md.num new file mode 100644 index 0000000..4b9026d --- /dev/null +++ b/articles/Host your own services NOW.md.num @@ -0,0 +1 @@ +63 diff --git a/articles/I switched back to Microsoft Windows.. here's why.md b/articles/I switched back to Microsoft Windows.. here's why.md new file mode 100644 index 0000000..2537fa7 --- /dev/null +++ b/articles/I switched back to Microsoft Windows.. here's why.md @@ -0,0 +1,91 @@ +# I switched back to Microsoft Windows.. here's why + +2023-04-01 + +As you guys may know if you have been a speedie.site reader for a while, I was a +Gentoo user, and recently I switched to using Arch full time. However, I am yet +again switching operating system because I just found out Windows is the best +operating system ever made. + +## Linux sucks, but Windows is awesome! + +Now, most of you probably use some open source Linux distribution on your +computer. But Linux is open source, and that's bad. That means Russian +hackers can steal your porn collection because of course they can see all the +source code and backdoor it. When you're using Microsoft Windows on the other +hand, the only one who can access your data is Microsoft, who will send that +data to the NSA. This also makes sure your data is safe, and that you're +following the law like any good citizen. When I'm using Windows I feel safe +and no malware has access to my data. The same cannot be said for Linux or +any other open source operating system + +These Linux users who never go outside or shower will say that this is malicious, +or that it is spyware, or any other nonsense but the fact of the matter is the +government already knows everything about you anyway. You should not care about +privacy if you have nothing to hide, so of course Linux users have a lot to +hide. The government would never do anything bad anyway, they only +want the best for you. + +## Tiling window managers suck + +Why would you use a tiling window manager? Only hackers use those. Tiling +window managers are also really hard to use, I mean think about all the keybinds +you need to remember to get good at using one. + +What about speedwm? I'm just kidding, I've been secretly using GNOME for years, +and I was never using speedwm in the first place. Hating Wayland? Actually, +I've been using a Wayland session on GNOME for a long time now. As we all +know, X11 is old and slow, and it's not written in Rust so that makes it +instantly bad. spmenu? It's just rofi with a theme. + +C programming language? Hell no, it's so hard to learn and it's so old. +Real programmers use JavaScript for the frontend and Rust for the backend. Recently +though, I've started using C# which is superior to both of these in +every way. We all love Micorsoft. + +## Vim is only used by furries, neckbeards and weirdos + +Vim is a meme Linux users force onto new users. In reality, Vim is hard to use and +it's so slow, I can't even figure out how to exit it. If I can't even exit it, +how can I use it to write code? Why wouldn't you just use a mouse anyway? +It's not 1983 anymore, we have modern, proper computers for real people now. +The only people who still use Vim are neckbeards who want to look cool on +the internet but in reality don't have a life. + +Visual Studio Code on the other hand is the greatest code editor ever and +it's what I've been using for months now, while people were under the +impression that I'm an avid Vim user. It's "open source" so that the +Linux neckbeards will use it, but uses a mouse, because it's 2023 +and if you're not using a mouse for everything except typing, you're +lost in the past. It also supports JavaScript plugins and has a lot +of Microsoft telemetry, so they know you're doing a good job +writing programs for the future. + +## Installing programs + +Linux users claim that using their terrible package managers is better +than downloading executables from the internet directly. This is just +not true, because the package managers can be hijacked remotely by Russia +to spread propaganda to all of the users. This doesn't happen when you +download random executables from the internet, because Microsoft Defender +is guarding your computer, and has a 100% success rate. As soon as malware +tries to attack your computer, Microsoft Defender is there to stop it. + +## Software minimalism + +Software minimalism is all a big joke. Why do you need your computer to +use 100MB of system RAM idle? Unused RAM is wasted RAM. Microsoft makes sure +to leave no RAM wasted, which makes it much better. Unlike suckless, Microsoft +makes feature complete software that normal people can use. In fact, +suckless is just a software project created by Microsoft's worst employees +created to trick Linux users into thinking Linux is unusable, thus getting them +to move over to Windows. Microsoft makes sure people join the beautiful land +of Windows, where no one falls for memes, and everyone is secure. + +Conclusion then. After I found out Windows is better than Linux, I have +decided to stop working on my meme projects, and join Bill Gates in +helping him build the best operating system for normal people. Linux +furries and neckbeards, join the land of Microsoft today, stop using the +Matrix meme, come back to Discord, assist Microsoft and the NSA in +catching criminals, and become a real member of society today. +It's only a $100 operating system. diff --git a/articles/I switched back to Microsoft Windows.. here's why.md.date b/articles/I switched back to Microsoft Windows.. here's why.md.date new file mode 100644 index 0000000..954ad93 --- /dev/null +++ b/articles/I switched back to Microsoft Windows.. here's why.md.date @@ -0,0 +1 @@ +2023-04-01 diff --git a/articles/I switched back to Microsoft Windows.. here's why.md.num b/articles/I switched back to Microsoft Windows.. here's why.md.num new file mode 100644 index 0000000..59343b0 --- /dev/null +++ b/articles/I switched back to Microsoft Windows.. here's why.md.num @@ -0,0 +1 @@ +53 diff --git a/articles/Important site update (and the Matrix).md b/articles/Important site update (and the Matrix).md new file mode 100644 index 0000000..c5c2ed7 --- /dev/null +++ b/articles/Important site update (and the Matrix).md @@ -0,0 +1,33 @@ +# Important site update (and the Matrix) + +2023-03-15 + +I'm going to keep this one short and to the point. As some of you may know, +my domain is going to expire. It is going to expire on the 31st of March +2023, which is not far from today and that's what I'm going to talk about. +For those of you that don't know, my website uses a "free" TLD (top level +domain). This seemed like a good option last year, but as I want to +continue this stuff, it presents a problem. Freenom is the company that +provides the .gq TLD, along with a few more domains such as .tk. Freenom +has shown themselves to be problematic, and they have done things like +taking away domains from people after the websites have become too +popular. Renewing their domains is also difficult and annoying, and even +then doesn't work all the time for all people. + +Because of this, I decided to write this blog post, and to make sure my +readers have a place to keep up with me if my website does collapse, I've +created a Matrix channel which I recommend you join. You can join it +[here](https://matrix.speedie.site). You can start with Element, it's all +free software unlike the previous Discord server. I don't plan on making +this a big thing like Forwarder Factory was, and in fact I don't want that +either. This is simply going to be a small place for me to talk to my +readers, discuss the website and other things like that. +Either way, my domain expires March 31st if I'm unable to renew it. If I +manage to renew it, you can continue using the site like normal for an +additional year. Otherwise, I'm simply going to purchase a new domain. I do not +yet have another domain, which is why I recommend you join the Matrix channel. +That's really all I wanted to say, as the writer here I think it is important +that you are informed about everything. My website code is all available for +free on Codeberg so you can still have that if you want. + +Thanks for reading, have a good day! diff --git a/articles/Important site update (and the Matrix).md.date b/articles/Important site update (and the Matrix).md.date new file mode 100644 index 0000000..d3a8fa6 --- /dev/null +++ b/articles/Important site update (and the Matrix).md.date @@ -0,0 +1 @@ +2023-03-15 diff --git a/articles/Important site update (and the Matrix).md.num b/articles/Important site update (and the Matrix).md.num new file mode 100644 index 0000000..82cced2 --- /dev/null +++ b/articles/Important site update (and the Matrix).md.num @@ -0,0 +1 @@ +51 diff --git a/articles/Important update regarding the site.md b/articles/Important update regarding the site.md new file mode 100644 index 0000000..2313cca --- /dev/null +++ b/articles/Important update regarding the site.md @@ -0,0 +1,28 @@ +# Important update regarding the site + +2023-04-14 + +I will keep this one short so you can actually read through it. Yesterday +(13/04/2023) I purchased a domain, because as we all know I do not trust +Freenom to keep my site up. This domain is a lot more reliable, however it does +mean you will have to swap out '.gq' for '.site'. I have redirected **some** parts +of my site. I have redirected the main `speedie.gq` domain, and I have also +redirected rss.xml so that RSS readers won't complain. You should still change +the URL, however if you exclusively consume my website through RSS you will get +the message anyway because of this. Finally I redirected the wiki. + +Switching over is not hard. The page is identical, and although SSL was not +functioning earlier today, I have resolved the issue. So to switch over, just +replace 'speedie.gq' with 'speedie.site'. This is especially important if you +use Arch and my repository. If you do, you must edit `/etc/pacman.conf` and +replace the URL. There may be a few sharp edges as of now, as I simply ran a +few `sed` commands on the old site without looking through it properly, if there +are issues please [email me](mailto:speedie@speedie.site) so it gets fixed. +I should also add I moved from Nginx to Apache a few days ago. + +Anyway, that was just a short blog post about something relatively important. +I will *probably* keep the speedie.gq domain updated as well, but I cannot +guarantee it will work properly. If you have any questions, feel free to +email me, or simply join the +[Matrix space](https://matrix.to/#/#speedie:matrix.org). Either way, that's +it, have a good rest of your day! diff --git a/articles/Important update regarding the site.md.date b/articles/Important update regarding the site.md.date new file mode 100644 index 0000000..d07ce43 --- /dev/null +++ b/articles/Important update regarding the site.md.date @@ -0,0 +1 @@ +2023-04-14 diff --git a/articles/Important update regarding the site.md.num b/articles/Important update regarding the site.md.num new file mode 100644 index 0000000..fb1e7bc --- /dev/null +++ b/articles/Important update regarding the site.md.num @@ -0,0 +1 @@ +54 diff --git a/articles/Normies are destroying GNU+Linux.md b/articles/Normies are destroying GNU+Linux.md new file mode 100644 index 0000000..5688442 --- /dev/null +++ b/articles/Normies are destroying GNU+Linux.md @@ -0,0 +1,128 @@ +# Normies are destroying GNU+Linux + +2023-03-09 + +So, because this blog post marks blog post number 50, and because the first +blog post is 1 year old today, I thought to celebrate I'd do a rewrite of +my first blog post, which still holds true, actually more so than when I +intially wrote it. Granted, the original blog post is terrible, it was +fueled out of frustration and nothing more so let's give the topic the +chance it deserves. + +As well all know, GNU/Linux is an operating system and it has always been +the outcast, it has always been less popular than other operating +systems like Windows and macOS. Out of the outcast operating systems like +BSD, Haiku and more however, it's pretty popular and it's growing in +popularity. While this may seem like a good thing at first, when you +actually dig deeper into what that means for GNU/Linux, you'll find many +problems and I want to talk about those today. +So let's go back into the early days. Linus Torvalds developed the Linux +kernel, which was used in combination with the GNU project. This means +we now have a completely free software operating system. Great, now we +don't have to use spyware nonfree software that doesn't respect your +freedom anymore and everything is good for the small userbase. +Previously GNU/Linux followed the UNIX philosophy rather closely, which +is what made it so great. Of course there were exceptions to this rule, +such as X11 (and today Wayland), however most software was minimal, +and closely followed the UNIX philosophy like it was a religion, +as that was expected out of software. + +As GNU/Linux got more mainstream and normies got their hands on it, +this freedom, this minimalism, all this stuff that made GNU/Linux so +great started to disappear. When normies found this free operating system, +naturally being normies they didn't want to actually learn anything about +minimalism and free software, and certainly didn't want to enjoy any of +the perks of it. Instead of that, they initially whined and complained +about how it was different from what they're used to. And we, members +of the GNU/Linux community in response did everything in our power to +make the "Year of the GNU/Linux desktop" happen. Except.. + +We didn't. In response to normies complaining, we as a community at large +started developing garbage, bloated software that throws everything that makes +GNU/Linux and UNIX in general so great in the trash. We're no longer +using text streams, we're no longer writing quality software with +quality code, instead we're focusing on developing libraries on top of +libraries that just add bloat to a project and create huge basically +packages of software in an effort to please normies who refuse to +appreciate the beauty of UNIX-like operating systems and just wanted to +stick to what they're familiar with. + +Here's the thing, If you're this kind of person who doesn't want +to learn GNU/Linux, you don't want to learn about UNIX-like +operating systems and you don't want to spend any time out of your day +learning this stuff then why even bother using a new operating system +in the first place? At that point, you might as well stick with Windows +or macOS. But alright, fine. We can still have *our* section of the +GNU/Linux community where traditional UNIX/Minimalist views are +still appreciated, right? Well, no because eventually programmers +start writing software which of course depends on all this normie +software which is absolutely awful and now it becomes almost +impossible to have a functioning system on GNU/Linux without +this garbage software. + +I haven't given any examples yet, but in my first version of this +blog post I referred to Snaps, AppImages and Flatpaks, and while those +do still meet the criteria here (although not in the present), +I want to give some more examples which might make more sense. +First, systemd. systemd is a collection of tools for GNU/Linux, +and although many people hate systemd because it is "an init system", +it is really a suite of tools. Therefore calling it bloated is not +justified. However what is justified is valid criticism towards it. +systemd provides a tool named "logind". So many programs depend +on this, it is pretty much impossible to have a modern GNU/Linux +system without this program installed on your computer. Now, +that should be taken with a grain of salt because there +are many different implementations of this tool, and those of +you that use Gentoo may be familiar with one implementation +called elogind. Still, I think this is an excellent example of +dependencies that are used so much you cannot escape them. + +But there are so many programs like these that we can't really +escape, and the cause of these programs existing is usually +the same. Normies want "easy" software, so in response we write +terrible software which a normie will think is easy because +Windows is terrible. However the worst of it came around the +time Linus Tech Tips and all these other well known technology +"entertainment" channels started covering GNU/Linux and giving +it attention. When that happened and Windows/Mac users gave +this OS a proper chance, developers around here scrambled to +write as much normieware as possible to please these new users +in the hopes of converting them into GNU/Linux users. Of course +this failed, and just resulted in more terrible software. + +I call this the "gaming wave", because suddenly all these gamers +(often with NVIDIA graphics cards) came over here, because +that's what Linus Tech Tips' fanbase is and wanted to play +games. Of course, this failed because despite the effort from +the people who play games around here, most GNU/Linux users +don't really play games. In fact I barely play games myself +anymore. I have nothing against people who play games, but +the people who play games on GNU/Linux certainly have some +blame to take here. + +Lastly, before I end off this blog post I want to mention +a few things regarding Wayland. In short, I'm definitely +against it and that's for a few reasons. Wayland brings +a lot of good things to the table, such as a cleaner +codebase, less screen tearing, perhaps HDR support +in the future, and so on and all that is fine by me. +No complains there. Where the problem starts to show +however is from a developer perspective. Yes, the +Wayland display protocol *is* more minimal than X11 +(that's not really an achievement) but a lot of that is +because the Wayland mess has been moved over to the +compositor forcing any developers to write thousands of +lines of just absolute junk. This is absolutely terrible, +and until the developers of Wayland change direction +(highly doubt they will), I'm sticking with X11 until +it's no longer feasible to do so. + +Either way, that's what I wanted to say, stop using +all of this stupid software whenever possible, and +become a based GNU/Linux minimalist. I plan on getting +a page up on replacements for stupid software which +will kind of act as a guide on how to get into GNU/Linux +minimalism for those of you that fell for this stupid +software. If you have any questions or thoughts, +feel free to send me an email.. and have +a good rest of your day. diff --git a/articles/Normies are destroying GNU+Linux.md.date b/articles/Normies are destroying GNU+Linux.md.date new file mode 100644 index 0000000..1e60e2b --- /dev/null +++ b/articles/Normies are destroying GNU+Linux.md.date @@ -0,0 +1 @@ +2023-03-09 diff --git a/articles/Normies are destroying GNU+Linux.md.num b/articles/Normies are destroying GNU+Linux.md.num new file mode 100644 index 0000000..e373ee6 --- /dev/null +++ b/articles/Normies are destroying GNU+Linux.md.num @@ -0,0 +1 @@ +50 diff --git a/articles/Swedish man rants about licenses again.md b/articles/Swedish man rants about licenses again.md new file mode 100644 index 0000000..a62dbd0 --- /dev/null +++ b/articles/Swedish man rants about licenses again.md @@ -0,0 +1,75 @@ +# Swedish man rants about licenses again + +2023-05-23 + +It is no secret that I strongly believe in copyleft licenses like the GNU +General Public License (often shortened to GNU GPL or GPL) and the Mozilla +Public License (MPL). Copyleft licenses as the name implies are the opposite +of copyright licenses. With copyleft licenses, the user has the freedom to +modify, study and distribute the software and source code. But unfortunately +in recent years copyleft licenses have fallen out of favor thanks to tech +companies like Microsoft heavily pushing too permissive licenses to developers. +These licenses (which I will call 'cuck licenses' from now on) rob developers +of their work. Now, it should probably be noted that I am not a lawyer, nor am +I more experienced in any legal system that most people. I'm just here to +talk about the best software license today. + +With cuck licenses, the developer writes the code and puts it out on the +internet like usual. The difference is there is nothing that prevents anyone +from forking it and changing the license. You might ask why this matters. +It matters because big tech companies like Microsoft, Google, Apple, Nvidia, +Meta, and many more will take these free software projects, change the license +to a nonfree license and no longer distribute the source code for the software. +Most of these cuck licenses **only** require that the license notice is kept in +every piece of code. However you're only distributing a binary though, the license +isn't noticeable anyway. + +I'm sure you can tell by now, but tech companies LOVE cuck licensers, because cuck +licensers do the work for them and for free. The companies then just steal that +source code and make their own proprietary variant. No attribution, no money, +nothing. Some developer writes the code for free and a big tech company will steal +it and make a nonfree spyware variant of it. When tech companies write software, +they will usually license their own software too under the BSD licenses or more +commonly, the MIT license. The MIT license is probably one of the worst +licenses out there in terms of stripping the developer of his/her freedom. The +user still has the freedom to use, study and modify the software. That is, +until a tech company forks the project and changes the license to a nonfree one. + +An example of a bad case of cuck licensing is MINIX, a portable UNIX like +operating system. Because this project is cuck licensed, Intel decided to fork +the project, apply some spyware modifications to it and relicense it under a +proprietary license so no one knows what the code really does. Now all Intel users +have this backdoor in their computer in what's called the Intel Management +Engine (ME). Or take Google Chrome. Google forked the Webkit engine and made their +own web engine called Blink. The Chromium browser which implements this engine +is free software, but Google Chrome (which is very similar) is a nonfree program +which does god knows what. + +But you, the developer can fight back against this by licensing your software under +a copyleft license. Copyleft licenses *usually* require that the forked software is +licensed under the same license. So if you license your software under the GNU +General Public License version 3, all copies of the software including forks are +going to be licensed under that same license. This is great for developers +because their code is always used for free software and not nonfree software. +It's also great for users, as it means there will be less nonfree software to +use and more free software to use instead. + +I should note that I switched all software I've written from scratch to the +GNU General Public License version 3 about a year ago or so from the MIT license +and it gives me more freedom, and it also means everyone who uses my software or +forks of my software is guaranteed freedom. It's a win for everybody, and it +means together we're working towards a more free computing experience for everyone. +It has its flaws though, which is why some may consider the LGPL or Lesser General +Public License. This license unlike the regular GPL allows embedding the software +in proprietary programs. This may actually be preferable in some cases, but in +general you should stick to the regular GPL. I know there are more licenses than +the GPL and MPL, but I'm not going to get into license specifics too much here. +I'm mainly talking about the GPL because that's what I +license all my software under. + +Conclusion then. Cuck licensers write the software for big tech companies for free. +They get nothing in return and users get a piece of crap proprietary program when +the big company forks the originally free software program. With copyleft licenses +on the other hand, the user is guaranteed the freedom to modify, study and distribute +the source code or program. Switch to the GNU GPL today or any of the other GPL +compatible copyleft licenses and truly become a free software computer programmer. diff --git a/articles/Swedish man rants about licenses again.md.date b/articles/Swedish man rants about licenses again.md.date new file mode 100644 index 0000000..81522b5 --- /dev/null +++ b/articles/Swedish man rants about licenses again.md.date @@ -0,0 +1 @@ +2023-05-23 diff --git a/articles/Swedish man rants about licenses again.md.num b/articles/Swedish man rants about licenses again.md.num new file mode 100644 index 0000000..8c61d23 --- /dev/null +++ b/articles/Swedish man rants about licenses again.md.num @@ -0,0 +1 @@ +58 diff --git a/articles/The Wayland experience.md b/articles/The Wayland experience.md new file mode 100644 index 0000000..413df5c --- /dev/null +++ b/articles/The Wayland experience.md @@ -0,0 +1,160 @@ +# The Wayland experience + +2022-06-17 + +Today I want to talk about my experience using Wayland compositors and software, +as well as developing Wayland clients for Wayland using the `wayland-client` library. +I've talked about the protocol itself in the past, usually in a negative light +because that's how I see it for the most part, but after using Wayland for a bit +I have some more things to say about it, and I want to talk about those today. + +First of all, Wayland is **not** a display server, just like X11 isn't a +display server. X11 and Wayland are both display protocols, which then have to +be implemented. X11 has a standard implementation, called Xorg. While this +isn't the only implementation of the X11 protocol, it is by far the most +used one. This is called a display _server_. Wayland on the other hand does +not have a single implementation more popular than others, because each compositor +has to implement the Wayland protocol themselves. This can lead to issues if a +compositor doesn't implement a core part of the protocol. This means the compositor +is also the display server. But because implementing an entire display server and +following the Wayland spec is complicated and time consuming, libraries such as +wlroots and swl have been created, which implement a lot of the Wayland functionality +for you. This is really as far as standards go with Wayland, because every Wlroots +based compositor is compatible with each other. The problem now is everyone is +going to base on Wlroots, and for good reason because no one really wants to +write all that code. + +Except not everyone wants to use Wlroots. For example GNOME and KDE both have +their own Wayland implementation (because of course they do), and this leads to +problems such as software only being written to work with Wlroots based compositors +or GNOME/KDE. From a developer's perspective, you can't just leave out GNOME +because GNOME is incredibly popular and used by a very significant amount of GNU/Linux +users, but at the same time if you leave out Wlroots based compositors a lot of +power users aren't going to be able to use the software on their favorite compositor, +so no power users are going to be using the software. So the developer has to +support BOTH GNOME and Wlroots, and most likely also test on both Wlroots and +GNOME, unless the program has a significant enough userbase. GNOME has a history +of doing their own thing instead of following a standard, and making decisions +that only benefit GNOME and no one else, which is likely why they implemented their +own version of the Wayland protocol. Whether that's true or not doesn't matter, +because right now there's no standard implementation of the Wayland protocol, +leading to more work for the developer. + +As you probably know, about two weeks ago I finished porting my program +[spmenu](https://spmenu.speedie.site) over to Wayland. While I was working on the +port however, I almost immediately noticed how lacking Wayland really is in terms +of features. They claim this is for "security", but I don't buy this argument +for several reasons. spmenu has a feature to position itself at a specific X or +Y position on the screen, but in the name of security wayland-client +(the library used to create Wayland clients) does not allow you to do this. +I ended up disabling this feature in the final product, which really should not +have to be done. I get that this can't be done with a standard window, but this +is a layer window, meaning it's supposed to be layered above all other +windows, so it makes sense to allow it to be placed anywhere. + +The reason I don't think security is a valid excuse here, is because with the +wlr-layer-shell protocol you can grab the keyboard and (almost) all input, and +grab the focus all to yourself. That's a much higher security risk than allowing +the window to position itself anywhere. Instead of allowing a specific position, +we instead have anchors, allowing us to anchor the window to a predefined part +of the screen, such as top, bottom and center. Also, if you have programs +doing malicious things by positioning itself, you have a much bigger problem. +Wayland does do some things in the name of security that I think are somewhat +justified, such as not allowing a client to move another client, or read +keystrokes when the program isn't actually used. That's very useful for +keylogging and other nasty things. But at the same time, if you have malware +on your computer, then you have bigger problems than that, and there are +legitimate uses for logging keys or moving other clients, which now aren't +going to be possible anymore in the name of security. + +Alright, so we've established that Wayland has fewer features than X11, how could +things get any worse? GNOME has the answer to that. Because there's no standard +implementation, you can just choose not to implement certain features. wlr-layer-shell +is a unstable protocol, but despite this it's the only way to create a +run launcher that functions like.. a run launcher, at least on the Wlroots +implementation of Wayland. GNOME however doesn't implement wlr-layer-shell +so any programs that use wlr-layer-shell will not function under GNOME, +and spmenu is no exception to this. It doesn't make it any better that GNOME has +a very high authority over the direction Wayland is going in, and really the +direction GNU/Linux as a whole is going in. + +Okay, but what's Wayland really like to use for the average user? Mixed, let's +just say that. If you're using a desktop environment, chances are you don't even +notice any difference between it and the same desktop environment on X11, at least +none that isn't positive. If you're using a window manager on the other hand, +you're going to notice things right away. Many programs that you may be using +just will not function anymore, particularly the programs that capture the +display. Wayland shills will claim that Wayland has support for all your X11 +programs, but while that's not entirely false, anything that captures the +screen itself is going to be totally broken on Wayland. + +One thing I noticed fairly quickly is that screenshotting doesn't work. +I'm using a tool called `maim` for this, and maim is X11 specific. Great, use +XWayland right? XWayland doesn't work for this purpose, and as a result the +capture is just black. What about ffmpeg and x11grab? Nope, doesn't work and +all you get is a black screen. Turns out on Wayland you need Pipewire +(or another tool) to capture the screen, and ffmpeg doesn't support this, +so if you had plans of using Wayland and at the same time using ffmpeg to +capture your screen, you're out of luck. While replacements for the X11 +specific software does exist, much of it is very buggy, broken, not in +repositories or just not the same thing. Recording using ffmpeg can be +replaced using a command line utility called `wf-recorder`, but screenshots +are little more complex. + +On Arch, you need to manually compile a program called wayshot (a program that +functions as a maim replacement) because the version you can get from the AUR +is out of date and doesn't support using `slurp` (a slop replacement), meaning +you can't select. After that though, everything works pretty much as expected. +But what about copying the image to the clipboard? Well, on X11 we can just +pipe the image into `xclip -sel clipboard -t image/png`, but as you might expect +this isn't built to use Wayland natively. It `does` work, at least with XWayland +compatible compositors but to do it natively you'll want a replacement called +`wl-clipboard` and the `wl-copy` command. The wl-copy command works pretty much +in the same way, pipe the image or text into it. Unlike with xclip though, you +don't need to specify a type, and wl-copy only supports one clipboard so you +don't need to specify a selection either. + +Normal X11 programs though that run in a normal window or floating window usually +work fine, and I was able to carry on using my X11 terminal emulator which is st +just fine, with no noticeable loss in speed. No configuration is required for +these to function with most compositors, although some don't support XWayland +such as Qtile, so with those you may not be able to use your X11 specific programs. + +What about Wayland compositors? Most of them are terrible in my experience. Maybe +there's some secret awesome compositor, but every single one I have used so far +has had some major flaw that makes it unusable. I started off my Wayland journey +on Hyprland because I hear that's what most people use. The default keybinds are +absolutely awful, and a good example of that is Super+q which doesn't quit Hyprland +or close a window, but rather spawns Kitty, which isn't even a Wayland specific +terminal emulator. Certainly a weird default. Even after some configuration +though, Hyprland has several issues. For one, if you set a wallpaper using +swaybg or hyprpaper the computer runs much slower, and Chromium seems to freeze +at random. This happens with all my computers, with both Intel graphics and AMD +graphics. I ended up determining that it was a problem with Hyprland because +with dwl,sway and river everything worked perfectly with a wallpaper set. +Most of these compositors also do not have a built in bar, sway is the only one +I found that has one, not even dwl which is supposed to be a dwm clone has a +built in bar, despite using way more lines of code than the original dwm. + +Wayland has several issues as well that make the entire product completely +unusable. For one, I have **never** been able to get it to work on my NVIDIA +GPU (GTX 1060 6GB) system. Not with the free software driver and not with the +nonfree `nvidia` driver. It's possible it works with GNOME or KDE, +but I have no interest in running any of those, and I don't care for desktop +environments. While it isn't fair to blame Wayland or Wlroots for this, +in practice I'm unable to use Wayland on my NVIDIA system, and as such I decided +it was worth mentioning. + +By the way, I should also mention that I have implemented Wayland screen capturing +into [dfmpeg-spmenu](https://git.speedie.site/speedie/dfmpeg-spmenu) +and [screenshot-spmenu](https://git.speedie.site/speedie/screenshot-spmenu) if you +want to use spmenu for screenshots or screen recording. This is also X11 compatible, +so you don't need to switch script whenever you switch back to X11. + +Anyways, I'm done with Wayland as of now. I will keep a session around to try +out my own software in and will continue to support Wayland in spmenu, but I will +not use Wayland anymore, and I am very happy to go back to dwm and X11. I may eventually +make a second part to this blog post where I talk about actual code and programming +in C for Wayland, but I'm going to end this blog post here. If you had an interesting +experience with Wayland or thoughts on Wayland, feel free to share it with me. +Thank you for reading, have a good day! diff --git a/articles/The Wayland experience.md.date b/articles/The Wayland experience.md.date new file mode 100644 index 0000000..8e015fb --- /dev/null +++ b/articles/The Wayland experience.md.date @@ -0,0 +1 @@ +2022-06-17 diff --git a/articles/The Wayland experience.md.num b/articles/The Wayland experience.md.num new file mode 100644 index 0000000..b1e7d26 --- /dev/null +++ b/articles/The Wayland experience.md.num @@ -0,0 +1 @@ +61 diff --git a/articles/Ungoogled Chromium: The best browser for most people.md b/articles/Ungoogled Chromium: The best browser for most people.md new file mode 100644 index 0000000..2bdb2f6 --- /dev/null +++ b/articles/Ungoogled Chromium: The best browser for most people.md @@ -0,0 +1,73 @@ +# Ungoogled Chromium: The best browser for most people + +2023-05-01 + +Today I want to talk about my favorite web browser which I have been using for +several months now and that is Chromium, specifically Ungoogled Chromium. +Ungoogled Chromium is the best browser because it's fast, it respects your +privacy, but also doesn't provide any extra bloat or anything, it's just a fast, +privacy respecting web browser that does everything you need and nothing more. +In a lot of ways it's the best web browser for minimalists, but also for normies +because it requires no learning coming from Chrome or whatever. + +If you are on Arch, you can get it from the AUR, and I also have a package available +in my arch repository, so if you're using speedie-aur you can +just `pacman -S ungoogled-chromium`. When you start it for the first time, if +you're coming from regular Chromium or maybe the horrible spyware that is +Google Chrome, you're going to notice that it looks a bit more minimal. That's +because most of the Google junk has been removed, so what you have is what you +actually need out of a web browser. By default, no search engine is +active/enabled though, but if you want one you can go to the settings like in regular +Chromium and simply add one. + +The second thing you're likely going to notice pretty quickly about Ungoogled +Chromium is by default it actually doesn't save cookies, so after you close +your web browser you have to log in again. Now, I consider this a feature +rather than a bug for security reasons, and while this isn't a security +oriented web browser, most of its users are privacy enthusiasts, so I consider +this a nice default. If you don't like this though, you can just change it in the +settings. If you're setting up this browser for a normie, you may want to +enable saving cookies, because in the society we live in normies would be very +confused when their web browser doesn't keep them logged in. + +Ungoogled Chromium is **not** hardened by default though. For good security I +would install ``JShelter``, `uBlock Origin`, `LocalCDN`, and a few other +privacy oriented extensions. I would probably also install `Vimium`, which +allows you to follow links using `f` and use general Vim-like keys to navigate +the web, and of course a dark theme of some kind. + +The reason I find this browser is better than others is +because it's based on the Chromium web engine making it extremely fast, +but it also respects your privacy by removing all the Google junk. Chromium is +a good browser outside of all that Google spyware, because Google knows what a +good browser is. A good browser is fast, minimal and allows you to view websites +and nothing more. Google has known this since the beginning, and that's why +this is such a good web browser. Other web browsers often fail at this. + +I should note that due to all the Google junk being removed, you can't actually +install extensions through the Chrome Web Store. However there's an extension +you can install manually, which will allow extensions to be installed from the +web store anyway, but you should RTFM for that. The extension is available +[here](https://github.com/NeverDecaf/chromium-web-store), and was designed +with ungoogled-chromium in mind. While you don't need it, it makes the process +of "manually" installing extensions a whole lot easier. It even does updating +for you, although it requires *some* user input. + +As if this web browser wasn't already excellent, The `--app` argument makes it +even more useful. In fact it makes all Electron applications basically obsolete. +If you do.. for example `chromium --app="https://speedie.site"` you'll pretty +much have an app for my website as the name implies just like Electron would +do, except it's using your existing web browser. This makes it slightly more +appealing. It even changes the icon to the favicon for the site. I'm using this +feature for Element (the Matrix client I use) and Discord. I combine this with +my run launcher to have super awesome web apps. + +Overall, I highly recommend this browser. While it's not the most secure +(you'd probably want GNU IceCat or LibreWolf for that), it's super fast, +it's free as in freedom and it's minimal and clean. It provides sane +defaults such as not storing cookies by default. It's a good web browser +for both normies and people who know how to use technology, because I +think both groups of people find its features appealing. If not, I guess +the normie can continue using Chromium and you can use Ungoogled Chromium +and get privacy from it. Thank you for reading, I highly recommend Ungoogled +Chromium, and have a good day! diff --git a/articles/Ungoogled Chromium: The best browser for most people.md.date b/articles/Ungoogled Chromium: The best browser for most people.md.date new file mode 100644 index 0000000..ea52216 --- /dev/null +++ b/articles/Ungoogled Chromium: The best browser for most people.md.date @@ -0,0 +1 @@ +2023-05-01 diff --git a/articles/Ungoogled Chromium: The best browser for most people.md.num b/articles/Ungoogled Chromium: The best browser for most people.md.num new file mode 100644 index 0000000..e1617e8 --- /dev/null +++ b/articles/Ungoogled Chromium: The best browser for most people.md.num @@ -0,0 +1 @@ +57 diff --git a/articles/Why I don't use Wayland (and how it can be improved).md b/articles/Why I don't use Wayland (and how it can be improved).md new file mode 100644 index 0000000..41ec65b --- /dev/null +++ b/articles/Why I don't use Wayland (and how it can be improved).md @@ -0,0 +1,143 @@ +# Why I don't use Wayland (and how it can be improved) + +2023-04-28 + +Today I want to talk about Wayland, and why I don't use it. In case you're a +normie and don't know what Wayland is, Wayland is this new display protocol +created by the people over at Freedesktop. They want it to be better than the +display protocol most GNU/Linux users are already using called X11. While I'm +not against the idea of a new display protocol, in my opinion Wayland is a +failure, and it fails at doing everything X11 did right, and that's what I want +to talk about here. Note that most of this will be from a developer's +perspective; if you're using GNOME, KDE or maybe even one of the many wlroots +based compositors, your experience on Wayland is probably going to be pretty good. + +## Terminology + +First, let's talk terminology. On X11 we have something called a 'Window manager', +and as the name implies it manages your window. The window manager is the root +window, meaning it's the first window. Other than that, it's just like any other +window you may have. This is quite powerful, because it means in theory anything +can be a window manager. You can try this for yourself on Xorg and xinit by +running `startx /usr/bin/firefox`. What you should have is an X11 session with +only firefox open and nothing else. This is why we have window managers, they +allow us to spawn more windows and place those windows wherever we want. Even +desktop environment users have a window manager, because your desktop +environment comes bundled with one. + +On Wayland and X11, we have something called a compositor. Let's ignore +Wayland's definition completely for now. On a basic level, the compositor provides +fancy effects such as transparency, rounded corners with anti-aliasing, shadows, +animations and other things you may or may not want. One of the most popular +compositors today is called Picom, and most standalone window manager users use +it, if they use a compositor at all. This works by creating buffer where these +effects are added, and then displaying the buffer to the user. This is why +older machines may feel slow when a compositor is running, it's just not +displaying that buffer quickly enough. + +In X11, a client is pretty much the same thing as a window. I am going to be +using the term 'window' throughout this blog post, but client is what I +usually use when referring to an X11 window. + +'Xorg' is an *implementation* of the X11 protocol, and it's the implementation +most users are using. There are other ones like XFree86, but most users use Xorg. + +## The compositor problem + +This is where Wayland's problem for me comes in. On X11 these two components are +separate, so I can pick and choose each component and just combine what I like. +With Wayland, they have decided to combine the compositor and window manager +into one program, which to make it even more confusing is also called a +compositor. Now, why is this so bad? + +- Less modular + +By combining the compositor and window manager, you're slowly making the display +stack less and less modular. The days of choosing your compositor and choosing +your window manager are now gone. It's all one big program, meaning even if you +avoid desktop environments you're still going to have one big program that does +everything. This is just not the way forward if you ask me. I believe the main +reason for this is "making the desktop easier for new users", but at this point +the GNU/Linux community should give up on new users who aren't willing to +learn our technology. + +- Window managers are so complex + +It is incredibly easy to make an X11 window manager, because again it's a window +like any other. You really just need to create a window, read atoms and finally +move/resize windows around. On Wayland you now also need to implement a compositor, +which adds a lot of complexity and room for failure. Even one of the more minimal +Wayland compsitors dwl, a dwm rewrite for Wayland has many more lines of code +than the original dwm, because now you also need to do the compositing yourself. +Not to mention, if you're using a minimal compositor like dwl, you can't have +fancy effects and a minimal window manager, that's just not possible anymore, +at least as of now. + +This added complexity led to libraries like wlroots being created, and its slogan +really says it all; "about 60,000 lines of code you were going to write anyway". +However even with wlroots you still need to implement compositing, there's no +way to have a separate compositor with your window manager. + +- No, a Wayland compositor is not a window like any other. + +As I said earlier, a window manager on X11 is a window like any other. The only +difference is it's the first window spawned (root window), and it is responsible +for creating, resizing and displaying all other windows, although this is technically +not a requirement. This is good because you can for example `startx /usr/bin/firefox` +and have an X11 session that runs Firefox. Nothing else, just Firefox. This goes +for any graphical program such as your terminal emulator, text editor, Emacs, etc. +On Wayland, this is not possible, because windows do not implement compositing +whatsoever. They are only responsible for creating themselves. + +- How about no compositor + +I think this is worth mentioning as well. A lot of X11 users simply don't use a +compositor at all. They deem it unnecessary, and it makes sense. If you don't need +transparency, fancy effects, Vsync and other nice features like that, why should +you waste your system resources on a compositor? Good luck omitting the compositor +when you're using Wayland. You can't. + +Those are the problems that come as a result of combining the compositor and +window manager. While I'm sure there could be benefits to combining the +compositor and window manager as well, I just cannot think of a single reason. + +## What change do I want to see? + +I want a more minimal display protocol. Wayland is more minimal so I think it +passes here. What I also want is a more *modular* display protocol, and this +is where Wayland seems to fail. X11 did this right, but I want it even more +modular than X11. Everything should be separate, as long as it doesn't harm the +user experience. Not to mention, more modular software is usually more secure, +because each module is much smaller and easier to maintain. + +I also want a library which allows creating BOTH X11 and Wayland clients without +writing any extra code for it. This would be ideal, although I'm sure there +are potential challenges from doing it this way. You might say, "Just use GTK +or QT" but they also require writing extra code for Wayland or X11 support. +This leads to developers not supporting one or the other. + +For example, I want to add Wayland support into spmenu. I'd be happy to do so, +but the problem is it would require rewriting the code for creating the +window, handling events, keybinds, clicks, drawing, mapping, and more. +It's just not something I want to deal with, which is why I've +chosen to not write any of my software to use Wayland native libraries. +There is XWayland, but to my knowledge there's no such thing in reverse. + +## Conclusion + +I want to mention that I'm very much open-minded towards a new display protocol. +I'm all for a new, more minimal, more stable display protocol. It's just that +Wayland makes it a pain to write compositors, and in many ways it's a downgrade +from X11, which is *really* old I might add. That's not to say Wayland has no +improvements and X11 is perfect. The most popular X11 implementation, Xorg +is extremely bloated and has a lot of legacy code that really doesn't matter +today and the protocol itself is probably not much better. + +It also has absolutely horrible security. But all things considered, I think X11 +just has much better ideas on what the desktop should be than Wayland does. If +Wayland improves the things I don't particularly like, I may end up switching +to it. But as of now, X11 works fine for me and the benefits of Wayland just aren't +worth it, so I am going to be sticking with X11. If you know of any solution +to this problem, I'd love to hear it, and I'd love to give Wayland a proper chance. + +Thank you for reading, have a good day! diff --git a/articles/Why I don't use Wayland (and how it can be improved).md.date b/articles/Why I don't use Wayland (and how it can be improved).md.date new file mode 100644 index 0000000..d54a348 --- /dev/null +++ b/articles/Why I don't use Wayland (and how it can be improved).md.date @@ -0,0 +1 @@ +2023-04-28 diff --git a/articles/Why I don't use Wayland (and how it can be improved).md.num b/articles/Why I don't use Wayland (and how it can be improved).md.num new file mode 100644 index 0000000..f6b91e0 --- /dev/null +++ b/articles/Why I don't use Wayland (and how it can be improved).md.num @@ -0,0 +1 @@ +56 diff --git a/articles/Why most blogs suck.md b/articles/Why most blogs suck.md new file mode 100644 index 0000000..024ce12 --- /dev/null +++ b/articles/Why most blogs suck.md @@ -0,0 +1,35 @@ +# Why most blogs suck + +2023-04-19 + +Now that most of my issues regarding this site are resolved, I want to start +writing about something. I have a lot of topics I want to talk about, however +for many of these topics there's just not much content to them, so I apologize +for the length of some of these. + +Anyways what better topic to start with than this one. My blog isn't perfect, +I post a lot of garbage here quite often, but what pisses me off is when people +will write blog posts, have an RSS feed and then ruin it with one thing. +They will put about 1/10 of the blog post in the `description` tag, and then +they will have the blog post in full on their website. + +This is extremely annoying, because it means I have to open up my bloated web +browser just to view your blog post which could normally be read using my RSS +reader, which is designed for reading blog posts. What if I want to read your +blog post on the command line? Or what if I want to read your blog post when +I don't have internet? + +Good RSS readers like Newsboat and sfeed store the full feed locally, meaning +you can actually read the articles even when you don't have any internet +connection. But when you force me to go to your website, I can't just save it +when I do have internet and read the blog post whenever I want to read it. +Now, I know why you would do this. If you have a site, chances are you want +people to visit it. RSS is convenient, very convenient and I'm going to admit I +don't actually visit the sites for blogs I follow very often, usually I read the +feeds every day and then very occasionally visit the websites. But I still think +this is annoying. + +So, if you're going to have a blog and you plan on using RSS, please provide the +full blog post in the description tag. I know this can cause issues with +paragraphs, but you can steal my feed as a base if you want. Thanks for +reading, and have a good day. diff --git a/articles/Why most blogs suck.md.date b/articles/Why most blogs suck.md.date new file mode 100644 index 0000000..2b8383c --- /dev/null +++ b/articles/Why most blogs suck.md.date @@ -0,0 +1 @@ +2023-04-19 diff --git a/articles/Why most blogs suck.md.num b/articles/Why most blogs suck.md.num new file mode 100644 index 0000000..c3f407c --- /dev/null +++ b/articles/Why most blogs suck.md.num @@ -0,0 +1 @@ +55 diff --git a/articles/Yet another update post.md b/articles/Yet another update post.md new file mode 100644 index 0000000..b8639b0 --- /dev/null +++ b/articles/Yet another update post.md @@ -0,0 +1,57 @@ +# Yet another update post + +2023-06-03 + +Wow, look at that. Even more junk to fill my catalog and make it look like I've +done more writing than I actually have. Oh well. I'll get straight to the point. +At approximately 02:32 I quickly made the decision to move from cgit to Gitea +for hosting my Git repositories and projects. For this reason, links to the old +Git repositories need to be changed. This mainly applies to those of you that are +using speedie-aur, or speedie-overlay. I'm assuming that's quite few of you, but +just in case I'm putting this out there. + +If you're using speedie-aur, you'll need to edit `/etc/pacman.conf` and change +the `Server` to +`Server = https://git.speedie.site/speedie/speedie-aur/raw/branch/master/$arch`. +If you're using speedie-overlay you'll want to remove the overlay and add it again. +See [the repository](https://git.speedie.site/speedie/speedie-overlay) for more +information. The Arch wiki article has been updated to reflect these changes as +well, and so has the overlay.xml. + +I have also moved over a lot of GitHub repositories to my Gitea instance, such +as my Gentoo kernel for my ThinkPad and desktop, multiple OpenCore configurations, +and more, but all Codeberg and GitHub repositories are still accessible. It +should be noted though, that I plan on moving all website development to the +Gitea instance rather than Codeberg. + +What you may be screaming right now is WHY? I'll tell you why. Cgit is an +excellent Git viewer, but that's all it is. A git viewer. It doesn't handle your +repositories, no issue tracking, no pull requests, no users, nothing. This is fine +when you're the only one working on a project, as you're going to do most work +locally on your computer anyway, and then push using Git from the command line. +The problem is when you want to have any kind of collaboration, which is something +I realized today (and yesterday). As some of my projects are becoming increasingly +complex, I need a way for people to submit bug reports and fix issues. Emailing isn't +convenient for the user, and it isn't convenient for me either. Now that I'm using +Gitea, any user may create an account and simply create an issue or pull request. +There's not any more to it, just simple. If you're familiar with GitHub or even one +of the public Gitea instances like Codeberg, this is likely nothing new to you. + +Now, while I'm writing this blog post I also want to talk about some future changes. +I want to slowly move from w2wiki to simply a static website that people can edit +through issues and pull requests. In my opinion this is a lot better, not +only for security but convenience and flexibility. W2wiki is pretty good, but +it is definitely not designed with security in mind, and it isn't hard for anyone +to simply remove the entire thing with minimal effort, as we saw with the old +speedie.site wiki a while ago. + +While it is a static site for the most part, I may still be using PHP if necessary, +especially for maintainence. No JavaScript however, although it should be noted +that the Gitea instance does use JavaScript. There is just no way around it as +far as I know, so it will have to do. All the JavaScript is free as in freedom, +which is the important part. I have no plans to put JavaScript anywhere else on +my site though, as long as it's feasible. +Anyways that's just a small site update. Have been busy with my spmenu Wayland +port and other things like that, but now that it's complete I plan on posting +more blog posts, as I have a lot of things I want to cover eventually. That's +it for me, have a good day! diff --git a/articles/Yet another update post.md.date b/articles/Yet another update post.md.date new file mode 100644 index 0000000..a92966f --- /dev/null +++ b/articles/Yet another update post.md.date @@ -0,0 +1 @@ +2023-06-03 diff --git a/articles/Yet another update post.md.num b/articles/Yet another update post.md.num new file mode 100644 index 0000000..04f9fe4 --- /dev/null +++ b/articles/Yet another update post.md.num @@ -0,0 +1 @@ +59 diff --git a/articles/You don't need to justify your decisions.md b/articles/You don't need to justify your decisions.md new file mode 100644 index 0000000..54c0ffe --- /dev/null +++ b/articles/You don't need to justify your decisions.md @@ -0,0 +1,41 @@ +# You don't need to justify your decisions + +2023-06-08 + +I often hear people following my blog or just know me for one reason or +another, and usually it goes something like this: + +> Hello speedie I enjoy reading your blog. + +Thanks! + +> I’m using X nonfree software or Y desktop environment, sorry about that. + +This is the problem. I see far too many people apologize for their choices +in technology, but I want to make one thing clear. I am not here to judge your +technology choices. If you want to read my blog on Windows and/or Mac, use +nonfree programs, hate my software or ideas, or do something else I’m not +*personally* a fan of then you are 100% free to do so. You don’t need to +justify your use of software or hardware, that is a personal decision you are +making. I am not going to make that for you, and while I may not agree with +your decision, it is not mine to make. + +I may **suggest** replacements for the software you’re using if I believe it’ +s something you would benefit from (such as learning Vim or getting into +tiling window managers), but I’m never going to force you to use/do something, +or shame you for using the nonfree software or software I simply don’t +like. I am also never going to force you to believe the same thing as me, that’s +idiotic, and the definition of an echo chamber, something I’m very against. I don’t +want 15 speedie clones, you should have your own ideas, and I should have my own +ideas. If we agree then we do, if we don’t, then we don’t. I make decisions +you may find stupid, you make decisions I may find stupid, and if we don’t debate +each other’s ideas, we lose the ability to think for ourselves. + +That’s not to say it’s harmful to criticize the choices others make, but you need +to be willing to see both sides of the coin, and like it or not you need to accept +the choice the other person is making, whether you approve of it or not. That’s +just a short blog post for today, as I see this far too often, and I think it’s +important to say this. I’m probably going to talk about Wayland development, +Wayland libraries, Wayland protocols and Wayland implementations next time now that +I’ve truly given Wayland development a fighting chance to win me over. +That’s it for me, have a good day! diff --git a/articles/You don't need to justify your decisions.md.date b/articles/You don't need to justify your decisions.md.date new file mode 100644 index 0000000..dc68dac --- /dev/null +++ b/articles/You don't need to justify your decisions.md.date @@ -0,0 +1 @@ +2023-06-08 diff --git a/articles/You don't need to justify your decisions.md.num b/articles/You don't need to justify your decisions.md.num new file mode 100644 index 0000000..abdfb05 --- /dev/null +++ b/articles/You don't need to justify your decisions.md.num @@ -0,0 +1 @@ +60 diff --git a/articles/post01.php b/articles/post01.php deleted file mode 100644 index ba56d8e..0000000 --- a/articles/post01.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Stop making Linux user friendly.. sort of - - - - - - -
-

Stop making GNU/Linux user friendly.. ..sort of

-

2022-03-09

-

A problem that's getting bigger with each day is that we're making technology easier but it's also getting more and more "evil" with big tech companies collecting and selling our data for monetary gain.

-

So then we turn to alternatives (Usually free software and GNU/Linux) which is a good thing, more people caring about their online privacy. The problem is how we approach these new users. We want it to be easy for them but in the process of making it easy for new users we're also making it a nightmare for experienced users and slowly making GNU/Linux just as bloated as those proprietary operating systems.

-

What do I mean with "bloat" since that term is kind of a meme by now?

-

Nowadays most of the software we use is bloated. The websites you visit likely have a lot of JavaScript in them (Facebook, Google, Discord, Instagram, Twitter, etc.) which forces us to have bloated web browsers for viewing those pages slowing down older computers. Additionally this also requires a GUI program which some users might not want.

-

But even if you avoid the web there's still bloat in a lot of software. A lot of software on GNU/Linux now is packaged using Universal packaging like Snap packages (Canonical), Flatpaks (Red Hat), and AppImages.

-

Now since soydevs decide to package using these and since these are universal, every single package has to have support for every distro which obviously is very bloated and probably moreso than .dmgs containing a binary on macOS or a .exe since there are more GNU/Linux distros than macOS versions/Windows versions.

-

Thing is, when you're trying to keep your system minimal for multiple reasons (Could be old hardware or you simply like minimal software) these packages are just not an option. You might say, "Just compile from source" (as if I'm not already using Portage)

-

And yes, I can definitely see your point but the problem comes when software is absolutely proprietary, because you can't exactly compile software without the source code in your hands.

-

Now proprietary software is NOT minimal, obviously however whenever you need to install a piece of proprietary software you may in some cases be forced to use one of these bloated packages since the proprietary software developer is too lazy to actually use the distro specific package managers or at least provide a tarball for the user and leave it up to the distro maintainers.

-

So what are these universal package formats good for? Well, they're good for Windows/macOS normies who are used to things just-working without any tinkering. But problem comes when everyone starts adopting this new fancy packaging format. Because once these become standard (I definitely predict they will), you will be forced to use them (unless the software is free and open source).

-

TLDR; By using bloated universal packages and making it easy for the normies, you're making it harder for minimal GNU/Linux users/experienced users who REALLY hate universal packaging.

-

So please, if you're going to distribute software, please provide packaging for the distro's native package manager.

-

Have a good day

-
- - - diff --git a/articles/post02.php b/articles/post02.php deleted file mode 100644 index d5da56e..0000000 --- a/articles/post02.php +++ /dev/null @@ -1,21 +0,0 @@ - - - - -Notice for spDE users - - - - - - -
-

Notice for spDE users

-

2022-03-09

-

This is a notice for spDE users. It now comes with newsboat and this RSS feed built in. There may or may not be a keybind but you can access it from the terminal by running 'newsboat'.

-
- - - diff --git a/articles/post03.php b/articles/post03.php deleted file mode 100644 index 401b0be..0000000 --- a/articles/post03.php +++ /dev/null @@ -1,34 +0,0 @@ - - - - -Dear soydevs; Stop making desktop applications bloated. - - - - - - -
-

Dear soydevs; Stop making desktop applications bloated.

-

2022-03-10

-

Today I wanted to talk about something else. I guess it's kinda related to my previous post titled "Stop making Linux user friendly.. sort of". - Modern software has this problem, a very huge problem. "Bloat". Now bloat can be caused by many different aspects. Programming language, poorly written code, unnecessary features, etc. but the main one I wanna talk about is called "Electron".

-

Now if you're not familiar with Electron, it's basically a minimal version of Chromium designed to create individual desktop applications from HTML, CSS and JavaScript. This makes it easy to create desktop applications as long as you know a lot about web development.

-

In fact many desktop applications you might be using (Almost all of them are proprietary) use Electron. - Examples of these are: GitHub Desktop, balenaEtcher, Discord, Spotify, and yes, even a text editor, Visual Studio Code or as I like to call it, "SoyDev Code". - - If you've viewed my page, hate, you'll know that both Electron and the JavaScript programming language is there on my list.

-

Either way, JavaScript is a VERY bloated language and is often obfuscated making it harder to see spyware, even if it's TECHNICALLY open source. - Now JavaScript is becoming more popular in web development and this fact is pissing people who want a minimal system off. - So to make it worse, since Electron allows you to turn HTML+CSS+JS into a desktop application, this means JS will be used for software as well.

-

You might say, "I have a fast computer so I don't care if the software is bloated or not" and while that's a fair point, what if someone doesn't have a fast computer or just simply likes minimal software. Then they're essentially forced to use this bloated slow application just because a developer was too lazy to actually learn another language.

-

TLDR; The web is extremely bloated and since Electron turns "the web" into a desktop application, software on the desktop is getting bloated too.

-

So what do I want? I want developers to STOP using this Electron trash.

-

Thank you and have a good day!

-
- - - diff --git a/articles/post04.php b/articles/post04.php deleted file mode 100644 index 4eb8f8d..0000000 --- a/articles/post04.php +++ /dev/null @@ -1,35 +0,0 @@ - - - - -What you can expect from Project 081 0.6 - - - - - - -
-

What you can expect from Project 081 0.6

-

2022-03-10

-

This is an update for Project 081 users (if there still are any). As this project has slowly died I would like to finally finish it as I have been working on other stuff like gentoo-install, spDE, my RSS feed, sfetch and various other projects.

-

After I spent more time with GNU/Linux and stuff my older Mac OS X project kinda.. died. So therefore my goal is to finish Project 081 soon so that it's as good as it can possibly be. All the assets are (hopefully) complete however it has yet to be "compiled" together into an image for the user.

-

So while you wait, here's a list of a bunch of changes i've made to Project 081 as well as a few I'm going to do.

- -

That's basically what you can expect, if you have any more suggestions please create an Issue on GitHub.

-

That's all, Have a good day!

-
- - - diff --git a/articles/post05.php b/articles/post05.php deleted file mode 100644 index 238dbdf..0000000 --- a/articles/post05.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -Happy 20th Birthday Arch Linux - - - - - -
-

Happy 20th Birthday Arch Linux!

-

2022-03-11

-

So today, 2022-03-11 depending on your time zone marks 20 years since Arch Linux was released to the public. I would like to show some respect by - creating this very post. Arch Linux is still one of the best Linux distributions and I use it on a few machines.

-

Even though I personally use Gentoo, Arch Linux was what got me into minimal Linux distributions and bloat-free software so I believe - we should give it the respect it deserves.

-

So thank you Arch Linux for being "different" and being minimal. Although I don't agree with some of your decisions such as switching from OpenRC to Systemd, you're one of the most popular distros and managed to get many people away from the bloated - Linux distributions to something minimal and DIY. You even basically created Linux elitism by making an OS - that's difficult to install.

-

Happy 20th Birthday Arch Linux and thank you for reading this.

-
- - - diff --git a/articles/post06.php b/articles/post06.php deleted file mode 100644 index 173c54c..0000000 --- a/articles/post06.php +++ /dev/null @@ -1,36 +0,0 @@ - - - - -It's time to stop using Adblock Plus (seriously stop) - - - - - - -
-

It's time to stop using Adblock Plus (seriously stop)

-

2022-03-12

-

One of the most popular types of browser extensions have been ad blockers. Now there are so many ad blockers, most of them being absolutely terrible that it can be hard to pick one. - But fear not, just look for the highest rated one right? Well.. No. Because on most browsers Adblock Plus is the highest rated extension and therefore it's also the most popular.

-

But little do most users know that ABP isn't what it seems. You see, big tech companies pay the creator(s) of ABP to not block their ads. - You might say, these are what ABP calls "Acceptable Ads" but NO, these are not just whitelisted until you manually disable them, these are ALWAYS whitelisted.

-

Now, let's talk about what "Acceptable Ads" are. These are ads that ABP deems "Acceptable" and they likely get paid - to make these "Acceptable". - The reason this feature exists is obvious. Most normies don't spent time "tinkering" with their software and therefore probably use the default settings. - And "Acceptable Ads" are also enabled by default. So the user installs ABP thinking they're getting privacy and an ad free experience when that's not really the case.

-

Guess what makes it worse? ABP doesn't tell its users that they're being paid money by big tech companies. And because ABP is one of the most popular if not THE most popular - ad blocker its users are going to trust it no matter what.

-

So what ad blocker should you use? Well, you could go with the least bloated option which is to edit your /etc/hosts file but manually adding entries is extremely time consuming - and ultimately not worth your time so instead you can simply use the "uBlock Origin" extension which is available for Chromium, WebKit and Firefox based browsers.

-

uBlock Origin despite having a bad name in my opinion is definitely the best ad blocker. It's 100% open source and free as in freedom. Its filter is also public and if you really - want you can add it to your /etc/hosts manually. It has no "Acceptable Ads" trash which means money doesn't decide what's going to be blocked.

-

It also has a bunch of other nice features that other ad blockers lack such as preventing WebRTC leaks and disabling JavaScript, cookies, trackers and other stuff that you - might not want. It's definitely one of the best browser extensions and I highly recommend it.

-
- - - diff --git a/articles/post07.php b/articles/post07.php deleted file mode 100644 index 5e42eec..0000000 --- a/articles/post07.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - -rchat 0.4 is here (Now available on Arch and Gentoo) - - - - - - -
-

rchat 0.4 is here (Now available on Arch and Gentoo)

-

2022-04-24

-

rchat 0.4 has finally been released. This release doesn't bring much of note except a few commands.

-

However, you can now install rchat easily on Arch based distributions through the AUR and Gentoo using my ebuild repository.

-

To install rchat 0.4 on Gentoo, add my overlay, you can find out how to do so by following this link: https://codeberg.org/speedie/speedie-overlay.

-

To install rchat 0.4 on Arch, simply install the AUR package. You can use an AUR helper like 'yay' if you want. Usage with 'yay' is 'yay -S rchat'.

-

For other GNU/Linux distributions, you can head over to my GitHub and download the latest version. Or clone it using Git.

-

The latest release can be found here. Simply download, save to /usr/bin/rchat and chmod +x /usr/bin/rchat.

-

https://raw.githubusercontent.com/speediegq/rchat/main/rchat

-
- - - diff --git a/articles/post08.php b/articles/post08.php deleted file mode 100644 index 084207a..0000000 --- a/articles/post08.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - -Half an rchat (rchat 0.5 is out) - - - - - - -
-

Half an rchat (rchat 0.5 is out)

-

2022-04-26

-

rchat 0.5 is here. It brings a few more commands such as setting how quickly messages are loaded.

-

It is likely one of the last feature updates, as new features will come in the form of patches.

-

rchat now has it's own page on my website, you can check it out here: https://speedie.site/rchat.html

-

In addition to this, patches are now available. At the time of making this post, there's a .Xresources patch available for 0.5

-

Please be respectful and don't abuse the new feature.

-

- To install rchat 0.5 on Gentoo, add my overlay, you can find out how to do so by following this link: https://github.com/spoverlay/splay.

-

- To install rchat 0.5 on Arch, simply install the AUR package. You can use an AUR helper like 'yay' if you want. Usage with 'yay' is 'yay -S rchat'.

-

- For other GNU/Linux distributions, you can head over to my GitHub and download the latest version. Or clone it using Git.

-

The latest release can be found here. Simply download, save to /usr/bin/rchat and chmod +x /usr/bin/rchat.

-
- - - diff --git a/articles/post09.php b/articles/post09.php deleted file mode 100644 index 9973dd5..0000000 --- a/articles/post09.php +++ /dev/null @@ -1,34 +0,0 @@ - - - - -Everything I want to use is Chromium - - - - - - -
-

Everything I want to use is Chromium

-

2022-04-26

-

Good morning/evening/night gigachads. Today I wanted to speak about a problem. As you've probably read from the title which is 'Everything I want to use is Chromium', everything I want to use is Chromium.

-

No matter if you like Chromium or hate Chromium, it is a problem because centralization is a problem. In this case, centralization refers to a product with a marketshare so far above everything else, it's slowly killing any and all alternatives.

-

Back in the day, There were really only two web engines; Trident or whatever it was called (IE), and Gecko (Netscape/Firefox). This used to be a problem in the late 90s and early 2000s because Internet Explorer was about as dominant as Chromium is today. However as the mid 2000s came around, it was fairly balanced and you could get by with either web browser.

-

In 2008, a brand new "fancy" web browser came around called Google Chrome. Little did we know back then but this web browser would later end up essentially destroying the internet. Not the web browser itself, although it's pretty terrible and normies tend to use it, but rather the web engine it had, named 'Chromium'. Now Chromium is based on another web engine called WebKit. The problem is that Chromium is controlled by a big tech company and even worse, a big tech company with advertising as their main goal.

-

Now, Chromium is a free software project but since Google, the evil advertising company has the final say about what goes into the project and not, it's not something you should depend on. Chromium ended up being (and still is) the fastest web engine. This led to new websites relying more and more on Chromium. And as the result of that, most web browsers created nowdays are based on the Chromium engine.

-

Slowly, Chromium gained massive marketshare and fast forward to today, it's by far the most popular web engine out there. Essentially what we've done is given Google the power over all of our free software projects.

-

Not only that but with massive marketshare came web centralization. Google, the evil company has a monopoly on advertising, hosting and video sharing and even web searching. Who is to say they won't use their monopoly and power for evil in the "free software" project Chromium which is in most web browsers today?

-

Mozilla, the creators of Firefox and other free-software projects like Thunderbird don't have advertising in mind and rather try to encourage a free and open source web. However due to bad decisions and Gecko being slow, Chromium has taken over and now Mozilla is really struggling to keep the Firefox project going.

-

You might say, "just fork Gecko" and while that would be valid, Gecko is REALLY difficult to work with and that's the problem. You can't just easily create a browser based on Gecko because it's too difficult and time consuming.

-

Now, I'm not gonna go too in depth on this but many DESKTOP applications are also becoming Chromium. The reason is that soydevs have essentially stopped making regular Desktop applications and are instead using something called 'Electron'. Electron is basically a minimal (but still EXTREMELY bloated Chromium) which is even worse because even if you avoid Chromium for your web browser by using a Firefox based browser like GNU/Icecat, Tor, Firefox, Waterfox, Librewolf, etc. you'll still have Chromium based applications on your system.

-

It's getting really common. balenaEtcher, Discord, Spotify, Telegram, etc. desktop clients are all using Electron/Chromium.

-

So what do I want? I want a decentralized web. To support this, we need to somehow grow Firefox and Webkit based browsers' marketshare so that the marketshare is more even. So that, if Google eventually destroys Chromium and makes it a spyware monopoly, we have another engine to fall back on.

-

A good way to do this would be to bring back the old 'Choose a browser' prompt Microsoft was forced to show every time Internet Explorer was launched on Windows 7 and 8.

-

To contribute to this, I've decided to BAN myself from ever touching anything based on Chromium or Electron. Chromium might be great, or it might suck but I refuse to support a bloated, centralized web. If you wanna support a decentralized web, I suggest you do the same.

-
- - - diff --git a/articles/post10.php b/articles/post10.php deleted file mode 100644 index 47f027c..0000000 --- a/articles/post10.php +++ /dev/null @@ -1,31 +0,0 @@ - - - - -xinit is bloated - - - - - - -
-

xinit is bloated.

-

2022-04-30

-

Some GNU/Linux users are very serious about maintaining a minimal system. They use software like dwm as their window manager, written in C with very few dependencies (definitely check it out).

-

But even then, they keep using a bloated piece of software just to run an X session.

-

That program is 'xinit' or 'startx' as some people call it because that's the command you run to start an X session. To me, there is absolutely no reason to keep using such a bloated program when minimal alternatives exist. In fact, it's really easy to switch to a better alternative.

-

If you're running Wayland then you can ignore this post/throw that bloat in the trash, it's not for you. For the rest of us Xorg GNU/Linux chads, I'm going to walk you through a simple program called 'sx'. I've known about this program for months but never actually bothered to try it. As I quickly found it months later however, it is REALLY easy to switch over to sx, even on a system that's already fully set up.

-

To get started, change directory to wherever you want and 'git clone https://github.com/Earnestly/sx.git'. Now 'cd sx' and run 'make install' as root.

-

Now that you've got sx installed, it's time to start using it. If you're not sure how to use it, you can simply check the 'man sx' page.

-

To start a server, if your .xinitrc is in ~ then you can probably just run 'sx sh ~/.xinitrc'. You can use the exact same .xinitrc with sx as with xinit. Now, if you've moved your .xinitrc then it's the exact same command, just change the path.

-

If your X is configured properly and the .xinitrc is written properly, your window manager should start just like it did with xinit. Now, sx is just 36 SLOC of POSIX compliant shell so if you want you can easily make changes to it.

-

Unless you require very specific settings though, which is quite rare you probably don't need to modify it anyway.

-

sx does however have a few problems although I've only encountered one with dfmpeg/ffmpeg where it won't record. It's not a huge deal and it's probably just a dfmpeg thing. If it is and I manage to solve it, a new version of dfmpeg should be released soon.

-

Either way, sx is really everything you need an 'X starter' to do. Nothing less, nothing more.

-
- - - diff --git a/articles/post11.php b/articles/post11.php deleted file mode 100644 index 6492d03..0000000 --- a/articles/post11.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - -Smartphones are only smart because you're dumb. - - - - - - -
-

Smartphones are only smart because you're dumb.

-

2022-05-04

-

As a smartphone user;

-

Smartphones are evil. They're slowly turning us into braindead robots who only know how to consume but slowly lose the ability to think and to make decisions. They slowly require their smartphones to make decisions because their brains are becoming more and more useless.

-

Now, the problem people who understand how technology is bad for them is facing is normies. Normies don't understand how the technology they use affects them and they don't have any clue how it works. All they know is that it gives them a constant dopamine fix.

-

"Smart"phones are good for one thing; giving smartphone companies and government agencies all your data and slowly bluepilling everyone who uses them. They're forcing expensive pocket-sized pieces of glass and spyware onto people which are all running only proprietary software which likely will spy on you as is the case with nearly all non-free software.

-

"Smart"phones are slowly taking control over YOU and are now starting to "think" for you. This is a problem because it means you're slowly becoming useless, slowly becoming braindead. You are slowly becoming property of the big tech companies who made your device. The software is all proprietary (non-free) which means you have absolutely no idea what's going on.

-

You just have to trust tech companies and most people unfortunately do it without actually thinking for themselves. They think big tech companies are out here being nice trying to make the world a futuristic dream or something.

-

Now, for many Android devices and certainly Apple's hardware, you can't just replace the proprietary OS and proprietary bootloader with free software. Because they're not gonna allow that. You may be able to run a more free OS but you'll still have non-free software running on the glass and spyware you possibly paid thousands for.

-

So you pay them thousands for a phone which can do almost nothing compared to your computer, then they still spy on you and slowly devolve into a braindead robot.

-

Smartphones must be stopped before humanity is ruined.

-
- - - diff --git a/articles/post12.php b/articles/post12.php deleted file mode 100644 index ab476ce..0000000 --- a/articles/post12.php +++ /dev/null @@ -1,30 +0,0 @@ - - - - -I HATE APPLE!!! - - - - - - -
-

I HATE APPLE!!!

-

2022-05-23

-

Today I'm starting a new 'series' of blog posts essentially about how certain companies are evil. This one will be about Apple as I'm pretty sure you can tell if you even read the title of the post.

-

Before you call me a biased RMS fan who runs a FSF approved distribution, never goes outside, has Stallman posters and hates everything that isn't free software:

-

I am far from biased, in fact I used to run macOS as my main desktop operating system, used an iPad years ago and since 2020, have been maintaining a Mac OS X 10.4 retro project.

-

Even then, I believe Apple is an evil business, moreso than many other tech companies for one reason. No it's not their high prices. Actually it's worse than that. We can laugh all we want about the $1000 Studio Display stand but really, that's far from their worst. The real reason I hate Apple is because they manipulate the consumer.

-

If your first reaction to this is "HOW" then Apple managed to do it on you too.

-

So why is Apple evil? Apple is evil because they manipulate the consumer into thinking their products provide privacy for the normie (Which most Apple users are).

-

Need a good example? Simply watch their newest (at the time of writing) video called Privacy on iPhone. In the video they in sort of a weird way claim Apple and iPhone devices specifically allow you to disable app tracking. So why is this evil? Isn't this great for privacy?

-

If the normie consoomer who doesn't know any better tries to disable app tracking using whatever features Apple the evil company provides, Apple gets all that data for themselves. Now of course they claim they don't sell your data but how are you gonna know? Almost every piece of software written by Apple is ABSOLUTELY PROPRIETARY which means you have absolutely no idea what it does with all your data.

-

And while they have access to your data, the normie consoomer thinks Apple cares about your privacy and only wants the best for you. This means people who are now starting to care about privacy go out and buy iPhone devices thinking they're good for privacy when they're really not.

-

Sure, iPhones may be better than Samsung, Huawei, Xiaomi and the endless other companies when it comes to privacy but to think they don't track you is really stupid. A general rule is, if something's not "free and open source software" it tracks you. Apple stops other companies from tracking you but they track you themselves instead. At the end of the day, the data is still collected and sent to Apple so it really makes no difference in the end.

-
- - - diff --git a/articles/post13.php b/articles/post13.php deleted file mode 100644 index fb60cce..0000000 --- a/articles/post13.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - -Open source: Fake freedom. - - - - - - -
-

Open source: Fake freedom.

-

2022-06-05

-

Yep, I'm back with yet another rant because we totally don't have enough of those yet. I hope the next few blog posts are going to be.. more positive but I feel like this must be said.

-

This one is about free software and open source. This is probably my first blog post that has made be.. extremely angry while writing it. In fact I had to edit the finished post 5 times just because I kept insulting the people who support 'open source'. So please..

-

Stop using the term 'Open Source'.

-

By supporting 'open source' you're not supporting software that respects the user's freedom. Instead you're supporting 'fake' freedom. Open source is just as evil as proprietary software. The only difference is that the source code for the application is public. You don't wanna support proprietary software with a nice mask on, do you?

-

If free software is what you actuallysupport then please use the term 'Free software' or 'Libre software' instead. If you support 'open source' then you're supporting companies like Microsoft, Google, Apple and many more who don't care about your (free)dom but only the 'collaborate' aspect of open source.

-

They like open source because they get YOUR (as in people who write code for the project) work and code for nothing in return. Open source is important but it's just part of freedom.

-

In addition to this, many people who are unaware of the free software movement/project think these big tech companies are nice people who care about their users when this is far from the truth.

-

Open source does not guarantee the user's freedom. This is why tech companies support 'Open source' but not free software. Free software is evil to them because they want control, something free software doesn't and cannot allow.

-
- - - diff --git a/articles/post14.php b/articles/post14.php deleted file mode 100644 index 2e92c0f..0000000 --- a/articles/post14.php +++ /dev/null @@ -1,32 +0,0 @@ - - - - -Why I switched license from MIT to GPLv3 - - - - - - -
-

Why I switched license from MIT to GPLv3

-

2022-06-05

- image -

Like I said last time, I wanted to make some more positive blog posts so here goes, I guess!

-

In this blog post I wanna sort of explain why I switched to the GNU GPLv3 license after having used the MIT license for such a long time. I also hope this will be my last FSF/GNU related post for a bit but usually I just write about whatever is on my mind.

-

- So why did I switch license from MIT to the GPLv3?

-

It's fairly simple. Both are free software licenses but the MIT license and most other licenses are missing one specific point that I really like and it's the main reason I switched.

-

Most other licenses including the MIT allow anyone to fork the project and redistribute it just like the GPL but the problem is the license can be changed to whatever the fork author wants. This also includes a proprietary license which goes against what I want out of a license. I want to prevent non-free software, I don't want to help non-free software.

-

- How are you helping non-free software?

-

Essentially I'm writing their software for them, so then they can just fork it and make proprietary spyware out of it. This has happened to many different projects and you can thank these licenses that don't prevent a license change for proprietary firmware and other nasty stuff that (probably) runs on your GNU/Linux box. Some people may argue that the GPL is actually non-free because it doesn't let you fork under another license but I heavily disagree

-

At first it may seem like that but as soon as someone forks your software and changes the license to a non-free license you have MORE proprietary spyware so in the end you're causing more problems than you're solving. The GPL essentially tries to end proprietary software by providing a license which guarantees freedom like I stated in my previous post. which is something I support. So that begs the question. Should you switch to the GNU GPLv3 license?

-

Now, I would like to add that if you're heavily against the GNU project or the Free Software Foundation due to Richard Stallman, then you probably do not want to use the GPL. And most of the time the people who choose to NOT use the GPL for this reason cannot actually find a justifiable reason for their choice. I don't know about you and it's not my decision but either way the GPL is just a software license and therefore it really doesn't matter who wrote it. Just know that by using a license that doesn't prevent/stop non-free software, you're making the world a worse place.

-

If your goal in addition to providing users with freedom and a great piece of software then the GPL is probably for you. The GPLv3 license guarantees freedom for anyone who uses the software. Therefore in my opinion by using the GPLv3 license you are making the world a better place by stopping potential proprietary software.

-

That's all for this blog post I guess, bye.

-
- - - diff --git a/articles/post15.php b/articles/post15.php deleted file mode 100644 index 201da79..0000000 --- a/articles/post15.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Are GNU/Linux users elitist or are normies too stupid to learn? - - - - - - -
-

Are GNU/Linux users elitist or are normies too stupid to learn?

-

2022-06-06

-

Another day another blog post!

-

Windows/macOS users often call me an elitist GNU/Linux user but is that really deserved? Well, I personally don't think or care too much about people's opinions on me. After all, I have better things to do and since it's so common to call GNU/Linux users 'elitist', it doesn't really mean anything to me.

-

However, since this is so common I wanted to find this out for myself. So let's think for a moment here? Why do I write blog posts just like the one you're reading?

-

Well, for me it's because it allows me to say exactly what I think whenever I want. It's a nice way to (sometimes) express your anger at something. However I don't really view myself as an elitist. After all, I write blog posts like this one and write guides like this one. I went out of my way to help new GNU/Linux users in this case install Arch.

-

If I was an elitist I'd tell you to 'RTFM' like every Arch user ever. Instead I went out of my way to help you get started with Arch.

-

What I'm not about to do however is read the 'FM' for you. If you aren't capable of reading plain English then I will call you exactly what I view you as, an idiot or a normie.

-

In addition to this, it ALWAYS seems like the people calling me an elitist are part of this group. People who will complain about something being difficult without having the patience to read and perform. They will call anyone who uses software that they view difficult to use (for example Gentoo, Arch, or suckless software) an elitist. They can't seem to find one reason why anyone would actually want to use said software except to look cool on the internet.

-

Now I'm not gonna deny the fact that there do exist some elitist GNU/Linux users but they're the exception rather than the rule. Most people who use this (in the normie's eye difficult) software do it because it's more efficient once you know how it works. A good example of this would be Vim.

-

The 'real' elitists (in my opinion) are the normies since they consider anyone who uses X software an elitist even if only a few (but loud) people have an elitist attitude about the software they use.

-

The normies are proud to be normies. Just like we are proud to use this 'hard to use' software.

-

The difference is, we try to teach the normies this 'hard to use' software but instead of actually learning anything, they simply call us elitists. Therefore, I personally consider the normies the actual elitists.

-

To be clear, if you don't understand how to use X software then that's perfectly fine. What I do have a problem with is proud stupidity. Normies are always proud to be normies instead of learning. They take pride in being stupid.

-

That's all for this blog post. Have a good day!

-
- - - diff --git a/articles/post16.php b/articles/post16.php deleted file mode 100644 index 7aa9c63..0000000 --- a/articles/post16.php +++ /dev/null @@ -1,26 +0,0 @@ - - - - -Return of the rchat (rchat 1.0 is out) - - - - - - -
-

Return of the rchat (rchat 1.0 is out)

-

2022-06-07

-

It's been a while since I've updated rchat. Earlier today I decided to improve rchat since I noticed it had many flaws that I thought I could improve on.

-

rchat 1.0 brings many improvements. :help, :changelog and :history now have colors, Borders now scale based on the size of your terminal window.

-

In addition to this, you can now use ~/.config/rchat/rchatrc to set options. This might be useful if you wanna set settings without using commands. You can also set the border character using the ':set sep' command. :help, :changelog and :donate commands can be used without joining now.

-

You can reset all settings using the ':reset' command. You can also open my donation page by using the ':donate' command. Fairly small but very useful release. If you want to install it, you can clone the rchat repository and run make install as root.

-

Gentoo and Arch repositories should be updated soon.

-

Have a good day!

-
- - - diff --git a/articles/post17.php b/articles/post17.php deleted file mode 100644 index 156f277..0000000 --- a/articles/post17.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - -Website update - - - - - - -
-

Website update

-

2022-06-10

-

Since yesterday I've been working on a little website overhaul (mostly fixing errors and improving index.html) so this is just a quick blog post telling you about it.

-

Normally I wouldn't make a blog post about small changes like this because... I mean it's a website, it's supposed to be updated and changed frequently.

-

I've made some changes to the layout however and removed a few buttons. For example, my forks and dotfiles can now be found here instead. This was done to keep the front page clean and to the point. I also removed some project links but they're still up, just in the Projects page instead.

-

I added some fancy 90s style buttons as well to the footer of the front page because I thought they were cool. Let me know what you think about them and feel free to suggest more (License must be free to use). I also renamed a few blog posts but they're all still up. I plan on archiving a few blog posts but they won't be deleted.

-

That's it for the website update. Thank you for reading and have a good day! Hopefully next blog post will be a little more useful! 😃

-
- - - diff --git a/articles/post18.php b/articles/post18.php deleted file mode 100644 index 6547d5d..0000000 --- a/articles/post18.php +++ /dev/null @@ -1,30 +0,0 @@ - - - - -I HATE ATI!!! - - - - - - -
-

I HATE ATI!!!

-

2022-06-18

-
I HATE ATI!!!
-

It's been a bit since a proper blog post was made so today I'd like to rant about ATI who clearly are not capable of making a graphics card that works under GNU/Linux. Sounds familiar? NVIDIA? Actually, NVIDIA is still better at this because at least their GPUs ACTUALLY WORK under GNU/Linux.

-

So anyways. Yesterday I installed Arch on my laptop which has an ATI Radeon 5650m. It's some old Packard Bell machine from ~2009. The RADEON 5650m is not a fancy graphics card but it should be more than enough to have transparency in terminals with.. usable performance. Especially since it ran Windows 7 well (At least as well as such a spyware trash operating system can).

-

As always, installation boots fine, I install xorg-server, xorg-xinit and my build of dwm. Of course, this works fine and performance is good enough but as soon as i install picom and run the usual picom &, the entire computer slows down to the point where it's almost unusable and terminals take 10 seconds to spawn.

-

It's not an st issue either because dmenu also takes AT LEAST 10 seconds to open. Absolutely ridiculous for a simple run launcher/menu.

-

You might say I'm biased because it's only one computer and it might be broken or something, alright fair enough so I tried on another computer. I installed Arch on my Early 2008 iMac which has an ATI Radeon 2600XT and a Core 2 Duo processor. This Mac runs Mac OS X Snow Leopard great and Mac OS X Tiger through Project 081.

-

This time I also followed the Arch Wiki on ATI graphics cards and after an install of Arch and dwm, the thing is still unusable just like the Packard Bell laptop. Windows take ages to spawn and when they do spawn, are really really slow.

-

So I kill picom and right away, the computer actually works and terminals spawn instantly. Every single computer with ATI graphics have had TERRIBLE GNU/Linux support making them unusable if you want transparency.

-

Now, if you didn't know, AMD bought ATI and as such, ATI branded GPUs are no longer being produced meaning this isn't really a big issue if you only use new computers. In fact, my main desktop has an RX 570 + 580 (used for gpu passthrough) and it runs GNU/Linux with my dwm rice perfectly so AMD actually did something useful.

-

So to end this blog post off, If you want an older laptop/desktop to use with GNU/Linux, avoid ATI. If the computer is new enough to have an AMD graphics card then you are probably fine. You would probably also want to avoid NVIDIA due to their terrible proprietary drivers (although hopefully this changes now that kernel modules are "open source") leaving Intel as the best choice for GNU/Linux.

-
- - - diff --git a/articles/post19.php b/articles/post19.php deleted file mode 100644 index fe31c12..0000000 --- a/articles/post19.php +++ /dev/null @@ -1,37 +0,0 @@ - - - - -dwm: dynamic window greatness! - - - - - - -
-

dwm: dynamic window greatness!

-

2022-06-18

-

Alright so, how do I even start with this one?

-

I usually don't do software reviews but I think it's time to start doing some. I've been using dwm since around December after switching from i3 and it really doesn't get any better than dwm. In fact, I haven't switched window manager once since then (other than trying bspwm and some others for a short time).

-

dwm is by far the best window manager for GNU/Linux. Many beginners see it as difficult but it's actually really easy once you get the hang of it. And dwm like other suckless programs have very clear benefits which make it so great.

-

I've used i3, bspwm and awesome (which wasn't as awesome) and very quickly came to the conclusion that dwm works best for me. So, why should you use dwm?

-

Well, it all comes down to the suckless philosophy which is basically to write minimal software that only comes with the basics. Then, it's up to the users to create patches (in the form of .diff files) to add features to the software. This is an advantage because it means you don't have a bunch of features that you don't want to use in your codebase. But it also means there are no limits in terms of what you can do with the software.

-

Most window managers have a configuration file with set options that the window manager can read. This means you're sort of limited in what you can do with the window manager. dwm on the other hand is customized and modified by editing the C source code directly. Not only does this keep the software light and minimal (through not reading a bloated configuration file), but this also means you have no limits in terms of what you can do because it's all C code that can be modified in any shape or form.

-

The C programming language is also very minimal meaning you don't need to install a bunch of dependencies (Looking at you, Xmonad and Haskell) so if you run a GNU/Linux distro like Gentoo where everything is compiled from source, you won't have to worry about waiting 2 hours just to get a window manager installed.

-

People who are new to dwm and probably use i3 often say it takes a long time to make a change to dwm just because you have to recompile the source code but that's complete nonsense. To install my build of dwm which has way more patches than most people's build, you run 'make clean install' and it's done within one second. Even on older hardware, it's only going to take around 3 seconds.

-

But now, let's talk about the window manager itself and the features. Let's start with what it's like right after compiling and installing a unmodified build. You will reach a pretty minimal and plain desktop with a bar at the top.

-

In order to spawn a terminal (and make changes to dwm), you press ModKey+Shift+Enter. ModKey is by default 'Alt' but most people change it to the 'Super' so that it does not conflict with keybinds your applications use.

-

dwm comes with three layouts by default. A tiling layout (layout 0), a monocle layout (layout 1) and a floating layout (layout 2). Because dwm is a dynamic tiling window manager, windows are managed based on one of these layouts. You can add more through patches but this is what the default build comes with.

-

The tiling layout is a 'Master and Stack' layout. Half of the screen is dedicated to the window you last spawned (Master) and the other windows have to share the other half (Stack). The Monocle layout is very different. In the Monocle layout all windows are available but they're stacked on top of each other. The focused window is the only one visible. Finally there's a floating layout where all windows are floating. They can by default be moved around by holding Alt+Left click and dragging it around. Windows are spawned on the top left which is pretty ugly so many users including myself choose to patch in a center patch which means windows spawn in the center of the screen instead.

-

Something that I certainly noticed and that you will too if you're coming from i3 or something is that Alt+Shift+q does not kill the focused window but rather your ENTIRE window manager. To actually kill the focused window, you do Alt+Shift+C. This was something I just could not get used to so I ended up changing the keybind. It's definitely something that could be confusing if you're new to dwm.

-

As for RAM usage, dwm is basically as good as it gets. This is mostly because dwm is written in C and less than 2000 lines of it. Don't get me wrong though. dwm doesn't have any less features than other window managers. In fact, it actually has MORE because of community provided patches that can be found on the suckless dwm website.. These can be used with the GNU patch command present on basically every GNU/Linux system and are created with the diff command.

-

Patches are basically snippets of code from other people's dwm forks that contain additional features. For example, not everyone wants transparency but if you do, there's an alpha patch available which adds it to dwm. dwm can be as minimal or as bloated as the user wants, that's what's so great about suckless software.

-

So, conclusion then. Should you use dwm? If you want an experience that's nearly limitless and allows you the most control then yes. If you're the kind of person who wants the least amount of dependencies or a window manager as fast as it gets, dwm is probably for you.

-

However, if you don't like tiling window managers and don't want to control everything using a keyboard then you can just head back to your Ubuntu + GNOME environment that you are so familiar with. As for me, I'm going to continue maintaining my dwm fork because it has improved my productivity by a lot. My computer is much faster with dwm than it ever was before and consumes much less RAM.

-
- - - diff --git a/articles/post20.php b/articles/post20.php deleted file mode 100644 index df7d18a..0000000 --- a/articles/post20.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - -rchat 1.3 is out! (I AM GREAT AT PUSHING UPDATES!) - - - - - - -
-

rchat 1.3 is out! (I AM GREAT AT PUSHING UPDATES!)

-

2022-06-29

-

Alright so, rchat 1.3 has finally been released. Hopefully it does not break any existing patches. If it does then.. well, they should be updated shortly.

-

So, what changed with update 1.3? Mostly fixing bugs but I did replace ~ with $HOME as it works better. But in doing so, I introduced a massive bug and it's likely the dumbest thing I've done so far.

-

Now, to make this easy and quick, I decided to use sed to replace all instances. Normally this would be fine but the problem is, I ran sed -i "s|~/|$HOME/|g" which was a problem because if you are new to the terminal, $HOME is a variable defined on every GNU/Linux system. This means ~/ was replaced with /home/anon because /home/anon is my $HOME directory/variable. This meant rchat was broken for everyone except the people who happen to have their user account named anon.

-

So of course, this release fixes this issue and nothing more.

-

To install rchat, see the rchat page.

-

To update, if you are on rchat 1.2 or newer, simply respond with Y when prompted for an update.

-

If you are on rchat 0.5 or older (Latest release on the AUR as of 2022-06-29, pacman -R rchat and follow the instructions on the rchat page.

-

If you are on rchat 0.5 or older (Latest release on the splay overlay on Gentoo as of 2022-06-29, emerge --deselect rchat and follow the instructions on the rchat page.

-

That's it for this update, thank you for reading the blog post, have a good day!

-
- - - diff --git a/articles/post21.php b/articles/post21.php deleted file mode 100644 index d642cf1..0000000 --- a/articles/post21.php +++ /dev/null @@ -1,36 +0,0 @@ - - - - -PipeWire Review (RSS REVIEWS!!!) - - - - - - -
-

PipeWire Review (RSS REVIEWS!!!)

-

2022-07-04

-

I should probably start this "review" (calling it that would be stupid) off with a stupid little disclaimer; I am not an audio professional or ALSA expert. I am simply a regular user of a free software operating system.

-

I mainly use my audio devices for consuming content, editing videos and listening to music. That's it. I'm sure there are a few things that an audio professional would disagree with me on and that's fine.

-

In case I haven't made this clear enough before, I'm not usually a PipeWire/PulseAudio user. I find it kind of pointless because ALSA allows me to do pretty much anything I want and requires no setup except proper kernel options.

-

However, recently I switched to Arch on my ThinkPad X220 and because it doesn't offer any USE flags like Gentoo does, I'm forced to use either PipeWire or PulseAudio with Firefox. Not many developers support ALSA because not many people use only ALSA which means it is getting harder and harder to use ALSA for a lot of people. So what is the PipeWire experience like?

-

PipeWire to me is pretty much just PulseAudio-Improved. It's still an additional program I usually don't need but I can understand why it exists. A lot of audio related work would be an absolute nightmare to do on only ALSA so for most people, having an easy to use solution would probably be a good thing.

-

PipeWire is just that, you install it and it works. On Arch, you have three PipeWire related packages available, pipewire, pipewire-alsa and pipewire-pulse.

-

pipewire-pulse seems to be a compatibility layer for software that requires PulseAudio, and it also allows you to use software like pulsemixer to control it and pipewire-alsa allows you to control PipeWire using ALSA tools (such as alsa-utils) similar to pipewire-pulse. They're both probably worth installing.

-

I initially had to use PipeWire because it was a dependency for firefox which is the web browser I currently use but I decided to try using it for the rest of my system.

-

After installation, it requires no extra setup. You can use the same mixer you did with ALSA or PulseAudio if you installed the extra packages. PipeWire is mostly compatible with PulseAudio.

-

As for audio quality, I tested using both speakers, headphones (wired) and headphones using Bluetooth and they all work great. Usually I'm not a fan of wireless/bluetooth but I had to try it out. Bluetooth works significantly better on PipeWire compared to PulseAudio and even ALSA so if you are a fan of Bluetooth audio, you will definitely want to go with PipeWire.

-

On PulseAudio, the audio is very much out of sync and sometimes doesn't even want to connect properly. On PipeWire, it "just werks" after it's installed and connected properly.

-

I also tried compiling PipeWire on Gentoo and found that it compiled faster than PulseAudio so if you're trying to go for a minimal system, even though ALSA would be more minimal, PipeWire is a better choice.

-

Now let's briefly talk about Wayland support. I've heard PulseAudio support is terrible if not completely broken on Wayland but I cannot test that for myself because I'm not a fan of Wayland. If you're a Wayland user, you would probably want to do some more research into this or avoid PulseAudio entirely.

-

With all said and done; Will I continue to use PipeWire?

-

No.. sort of. I'm going to continue to use PipeWire on my ThinkPad because it is running Arch. I will however continue to use ALSA on my main machine running Gentoo because I don't see the need for anything else.

-

But do I recommend PipeWire? If you're going to use a binary based distribution, absolutely. It is a lot better than PulseAudio in many ways. However if you're using a source based distribution where you can choose to use only ALSA and that works for you then I would say continue to use ALSA.

-
- - - diff --git a/articles/post22.php b/articles/post22.php deleted file mode 100644 index a6abb0c..0000000 --- a/articles/post22.php +++ /dev/null @@ -1,30 +0,0 @@ - - - - -OH NO IM BEING CANCELLED ON TWITTER WHAT WILL I DO??? - - - - - - -
-

OH NO IM BEING CANCELLED ON TWITTER WHAT WILL I DO???

-

2022-07-14

-

A fairly new thing in internet culture recently has been "cancelling" people. It's a really cringe meme sort of created and spread around by these stupid Twitter users who don't do anything but tweet for 5 hours a day.

-

Let's imagine a scenario where we have Twitter users trying to cancel someone who has an internet presence elsewhere and also uses Twitter:

-

Usually what happens is they (as in the stupid twitter users) target someone who has an internet following elsewhere (although this does not have to be the case) who has a public opinion on something that isn't the most common and then try to link it together with something that is now in modern times considered socially unacceptable.

-

Then they will attempt to make the general public stop following or supporting them for having this usually pointless opinion "cancelling" the target in question. On the surface, to me, this seems like the usual nonsense created by Twitter users but actually, internet normies keep falling for it instead of being a strong internet chad who stands by their opinions no matter how unique, disgusting, or even illegal they are.

-

In modern day internet, it is socially unacceptable to criticize anyone who's even slightly out of the norm in terms of race, gender, sexuality or anything else, even if it's completely unrelated to the problem because they simply will not or cannot seem to stop connecting unrelated issues to people's identity.

-

What the targets in this case always seem to miss however is that they are pretty much cancelling themselves. The target will choose to think that THEY are in the wrong and because the Twitter users all follow the norm, they will say the same thing over and over again.

-

In reality no one is forcing the target to quit doing what they're doing except themselves. Instead of choosing to stand up for themselves and what they said, they chose to end their online presence because of one (likely small) thing that they said. If you want to avoid getting cancelled, it's really easy. Just do not care about what the stupid Twitter users think about your opinions.

-

No one can end your online presence except yourself and the owner of your platform (Twitter, Facebook, YouTube or yourself if you have a website). Acting like you aren't in control of your own social media profiles would be correct. But giving control over YOU and your internet presence to other people is a sign of weakness.

-

Simple advice; To avoid being cancelled, simply don't let anyone push you around on the internet, think for yourself and most importantly, stand up for your own opinions and actions, no matter what they.

-

That's it for this blog post, have a good day/night!

-
- - - diff --git a/articles/post23.php b/articles/post23.php deleted file mode 100644 index 19df333..0000000 --- a/articles/post23.php +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Why I ban software. - - - - - - -
-

Why I ban software.

-

2022-07-16

-

For some reason, people feel the need to ask me why I ban certain software. Why I ban myself from trying new software for seemingly made up reasons. In this blog post I explain the reason why I choose not to use certain software.

-

First of all, when I say 'ban' I simply mean I refuse to install or even try said software. This can be due to many different reasons however usually it's software that goes against my philosophy completely.

-

If you've been following my blog for a while, or know me on some other platform, you know that I only recommend free (as in freedom) software and this is for good reason. With free software, the user is in control, not the developer while with non-free software, the developer has a lot of power over the user and can hide malicious features in the software that will not ever be discovered.

-

So a lot of software I ban is automatically banned from my life due to freedom violating features. A good example of this would be Windows 11 which recently started changing the search feature in the start menu without the user's permission. For example, back in June during Pride month, Microsoft thought it would be a good idea to add a rainbow to Windows 11 users' search bar.

-

No matter what your opinion on the LGBT community is, there is no excuse for this and it's a great example of how you, the computer user is not in control. For this reason, I only promote free software and personally only use non-free software if absolutely necessary for hardware support on my computers (such as Intel ME or firmware for wireless).

-

Other software I choose to ban because of what the software was designed to do. A good example here would be Flatpaks, which aim to destroy the GNU/Linux operating system by creating distro independent packages that contain all dependencies no matter if they're required on the system or not. The goal is simplicity but this also means they're throwing minimalism and user choice out the window.

-

I've ranted about these a lot in the past but by banning terrible software like this, I'm doing my part in preventing this kind of software from taking over people's computers. Normies are not willing to do it because they value convenience above everything else, the only people who do this are the enthusiasts and activists and that's a shame.

-

So what change do I want to see?

- -

So, while we can't get normies to stop using this terrible software, we can definitely do our part. Thank you for reading this blog post, have a good day!

-
- - - diff --git a/articles/post24.php b/articles/post24.php deleted file mode 100644 index db0f866..0000000 --- a/articles/post24.php +++ /dev/null @@ -1,26 +0,0 @@ - - - - -What happened to spDE? (And announcement) - - - - - - -
-

What happened to spDE? (And announcement)

-

2022-07-23

-

Today's post is going to be short, and more announcement-y than usual. If you tried using spDE after around April, you may have noticed that it seems to no longer work. No this was not a failure on my end, it was done on purpose.

-

So first of all, if someone tries to use spDE right now, the script will quit with seemingly no error reported. This is because of a line I added to the start script on purpose. You might ask, why destroy the script on purpose?

-

The line was added because I had updated my builds of suckless software causing the builds to no longer compile. In addition, a few changes to distro repositories broke the script on Void GNU/Linux and Arch GNU/Linux based distributions. While this would be an easy fix, I had switched software too meaning the scripts were very out of date and as such not useful anyway.

-

So to prevent users' from destroying their GNU/Linux systems, I decided to break the script on purpose before it has a chance to install anything knowing that I would probably update or rewrite the script at a later date. Well.. It is July now and it is still broken and unmaintained.

-

This is where this announcement comes in. I have plans to completely rewrite spDE in a more maintainable way so that things can be added, swapped out and ommited without any trouble, both by the end user and by contributors in order to keep the experience as simple as possible. In addition, I'm going to provide great documentation (a lot already comes with my build of dwm) so really, spDE is going to be an install script for my build of dwm, any dependencies as well as other software I use with it. (music player, file manager, bluetooth, status bar, etc.).

-

Expect to see another announcement post shortly when it's complete! Have a good day!

-
- - - diff --git a/articles/post25.php b/articles/post25.php deleted file mode 100644 index 3e5325c..0000000 --- a/articles/post25.php +++ /dev/null @@ -1,34 +0,0 @@ - - - - -I left GitHub and you should too! - - - - - - -
-

I left GitHub and you should too!

-

2022-08-23

-

As we all (hopefully) know, especially the developers who read my blog, GitHub is by far the most popular Git service out there. It is also 100% free as in beer and offers a lot of features, even free hosting (although it does not allow the usage of PHP).

-

However, this comes at a price - Privacy. GitHub is not as nice as it used to be. GitHub used to only be a Git service but once it became popular, big tech does what big tech does best and decided to put their disgusting, money hungry hands on yet another product and this time it was GitHub because in 2019, Microsoft bought GitHub meaning everyone was right in expecting a huge downfall.

-

GitHub was definitely not perfect before it was purchased by Microsoft however if you are familiar with Microsoft and their background, you know their intentions were to dominate the programming and developer space. And why wouldn't they? They have created the C# programming language (and others), have a very popular code editor called Visual Studio and more recently, Visual Studio Code which is built using Electron. Guess who designed Electron? GitHub.

-

In addition, GitHub has their own IDE/text editor called Atom which just like Visual Studio Code, is also an Electron application. These two text editors, Atom and Visual Studio Code would kind of compete, and by buying GitHub, Microsoft would have complete control over both of these projects. After users of Atom got worried after Microsoft purchased GitHub, they said that they would keep both editors alive.

-

They did keep their promise for a few years but a few months ago, Atom was put to rest in a blog post named 'Sunsetting Atom.' which now makes Visual Studio Code even more popular. Microsoft does have the right to do this, and there will likely be forks of Atom, but it is clear what they want to do. They want the Atom users to move to Visual Studio Code.

-

So why did I mention this? Well, it's because you can no longer trust GitHub. Because it's now a Microsoft product, they want full control as they always do. Users have been worried for years and so have I but because I have so many projects, moving has been quite difficult and time consuming. And this is someone who is not a developer. Now imagine an actual developer behind many popular projects. It is a hassle and Microsoft knows this. Therefore most users are going to keep using GitHub as the time is just not worth it to them. And after going through this, I can kind of see why.

-

So, let's say you've had enough of Microsoft and their stupid proprietary services. Let's say you want to completely de-Microsoft your life. Where and how are you going to host your code?

-

Even though it may seem like everyone uses GitHub, it is not the only option out there. Another popular option is GitLab but just like GitHub, it is also spyware and offers even LESS features. It may not be owned by Microsoft but it is just as evil. If you are making the move, avoid both GitHub as well as GitLab.

-

If possible, avoid any services that are not usable without JavaScript. If you do this, it is possible to use the Git service with LibreJS which means you don't have to run any proprietary code just to view and use the website. For this reason, I chose Codeberg.

-

All of its JavaScript is free software and although LibreJS does block a few scripts, they are free software and can be verified as such. In addition, if you still want to block those scripts, the website will remain functional as those are only used for the text editor.

-

Codeberg also does not force you to use some obscure authentication making Git (the command line utility) difficult to configure and use. Codeberg "just werks" with minimal configuration. I prefer to use an SSH key to authenticate but there are also other methods available. Codeberg has a very similar layout to GitHub so there is basically no learning curve. It also offers some really useful features that GitHub does not such as being able to download patches/diffs for commits. This is really useful for me personally when comparing older commits to new ones of my software or reverting changes.

-

Moving repositories over can take some time and it doesn't allow you to automatically transfer over repositories like GitLab does however once you go through with it, it's really quick. You just create the repository, clone the old repo, clone the new repo, copy everything, commit and push. It can all be done with the command line Git so if you want, you can maybe even write a script to do it automatically.

-

Either way, I cannot recommend Codeberg enough and I am going to move all my repositories over. Many of my repositories have already moved and you can now find all my suckless builds, rchat and more there. I hope to be able to fully move soon, and although it's a lot of effort, it is going to be worth it.

-

That's it for this blog post, have a great day!

-
- - - diff --git a/articles/post26.php b/articles/post26.php deleted file mode 100644 index 0536be5..0000000 --- a/articles/post26.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - -Vim: You're wasting your life away if you don't use it. - - - - - - -
-

Vim: You're wasting your life away if you don't use it.

-

2022-09-04

-

Just a short blog post to break the silence.

-

Maybe the title of this blog post is a little rude to people who don't use Vim but it is true. When I say Vim, I don't specifically mean just Vim, there are many good forks of Vim out there such as Neovim which is what I use. However the productivity benefits of using a mode-based text editor like Vim are so great that I personally believe you're wasting your time (and therefore life) away by not learning and using it. In fact this entire website and this page was written in Vim (and later Neovim).

-

Vim has actually changed the way I use technology. It may sound strange; how can a "simple" text editor change the way you use your technology? The answer is simple. Vim forces you to learn a bunch of keybinds to get things done. But this is way better because it means if you know what you're doing, you can perform actions REALLY quickly and efficiently.

-

As soon as you use Vim, you'll realize how efficient it is and you will try to find and use software that follows the same philosophy. A good example of this is vifm. It's a file manager that tries to be Vim like and therefore efficient. And because you already know Vim, it doesn't have a massive learning curve anymore.

-

This is the main reason why so many developers like Vim. It's really efficient when you know how to use it and it doesn't get in your way. For example, to delete the line I am on using a regular GUI text editor, I may use my mouse to select that line and then I will simply delete it. In Vim, I just have to press dd and the line I'm on is instantly gone.

-

Another perk of Vim is that it comes preinstalled on almost all GNU/Linux distributions. The only distributions I've used that don't have Vim by default are minimal distributions like Gentoo, Arch, Artix, Void and similar distros.

-

This is useful when you're using SSH for example. When you're using SSH, you are usually not able to use GUI applications. Being familiar with a fast, powerful text editor that works in the TTY or through SSH is very important.

-

If you want to learn Vim, install Vim or Neovim and run Vimtutor in your terminal. It's not rocket science and anyone can and should do it.

-
- - - diff --git a/articles/post27.php b/articles/post27.php deleted file mode 100644 index b7a668c..0000000 --- a/articles/post27.php +++ /dev/null @@ -1,31 +0,0 @@ - - - - -I AM TOO AWESOME FOR SMARTPHONES! - - - - - - -
-

I AM TOO AWESOME FOR SMARTPHONES!

-

2022-09-15

-

I may be three days late to this but I have an announcement to make. I AM TOO AWESOME FOR SMARTPHONES! You heard me right, I have decided to abandon my smartphone. But how, HOW are you going to live without a portable tracking device with plenty of spyware to keep you too busy and consooming to care?

-

Well, simple. I simply don't consoom content when I am not home! In my opinion, it is not terribly difficult to make use of your time and at the same time not use a phone. Nowadays there seems to be this idea that when you're bored for just 5 seconds, you're supposed to pull out your phone and waste your valuable time away watching others waste their life away on social media, then go home, depressed, in a loop that repeats until the end of your life.

-

It is pretty clear to anyone who follows my blog that smartphones have permanently damaged society. It can partially be blamed on the fact that smartphones are so small, anyone can just bring them up quickly without any effort. However I would put most of the blame on the addictive social media that big tech companies (the same companies that produce the phones we buy) make us use.

-

Most if not all social media is designed to keep you using it for as long as possible, while tricking you into thinking your life is great and absolutely nothing is wrong with it. This is because it is an easy way to gain control over the user and his habits. This allows social media to take over anyone's life.. However that anyone is not going to be me.

-

In the last few months, I've been spending time deleting accounts and recently I deleted my Twitter account. I decided to do this because I absolutely hate Twitter and don't want a presence there. However instead of having a simple 'Delete account' button like social media from yesteryear had, if you want to delete your Twitter account you have to first deactivate it and then wait a month for it to become 'fully' deleted. (Really just hidden from the public website, the account likely still exists). If this isn't a great example of how social media is really social destroyer, I don't know what is.

-

Compare your one friend who uses all the spyware social media to someone who never or rarely uses the internet. Which one is more interesting to talk to. Who is going to pull up their phone and check their Snapchat notifications every 30 seconds? People who use social media constantly are just boring people, who absolutely suck, and have nothing interesting going on in their life to talk about, so they have to rely on social media to fill the void.

-

Thing is, No longer using smartphones really will not change my life in any way and the reason is, I was never wasting my life away on social media on my phone in the first place. I just.. never fell into the trap like so many other people have. However, I am doing this to send a strong message to everyone I talk to. I want to let everyone know that you DO NOT need a smartphone to live. By not bringing and using my phone everywhere, I'm bringing attention to the fact that I don't use a phone.

-

Not only does this give out a good message to everyone, but it also gives others a reason to talk to me. Nowadays it is uncommon to see people not bring their phone. In fact it is so uncommon YOU are the minority if you do not have a phone. Society EXPECTS you to have a phone. If you don't have a phone, everyone will look at you, shocked, like you're an alien from another planet.

-

So to end off this blog post, I would like to mention that if you find that you need your smartphone to live a life, consider doing what I am doing and will continue to do. Throw your phone in the old junk drawer filled with crap you've got in the basement, run outside, and enjoy the beautiful air and trees you've got out there. Talk to people, have a conversation, and find things to do.

-

Wasting your life away on social media and using smartphones is not normal. Just because society makes it seem that way does not mean it actually is. You do not have to take my word for it, you will notice the difference within a day. You will be a much more interesting person to talk to, others will be more likely to talk to you, because you stick out and most importantly, you've escaped the big tech for loop.

-

Do good things with your life. You only live once so use the time you have wisely. This blog post is now done. Thank you for reading! Throw your phone in the trash like me and get a life!

-
- - - diff --git a/articles/post28.php b/articles/post28.php deleted file mode 100644 index 7fafe00..0000000 --- a/articles/post28.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - -SHILL POSTS ARE BACK! fontctrl (Fonts on GNU/Linux-Improved) - - - - - - -
-

SHILL POSTS ARE BACK! fontctrl (Fonts on GNU/Linux-Improved)

-

2022-09-16

-

THE SHILL POSTS ARE BACK! Fonts on GNU/Linux absolutely suck so I wrote a script in suckless fashion to fix them. So, what is wrong with GNU/Linux fonts and how does title related fix the problem?

-

First problem is manually installing them. This in itself would not be a problem but the issue here is that there are about 3 million different paths where a font should go because of conflicting standards.

-

fontctrl addresses this issue because it introduces two modes. Global and user. When you install a font globally using fontctrl, it will be located in /etc/fontctrl/fonts/. This of course requires root so the solution was to add a '--user' flag which will install it for the current user only. If this mode is used, the fonts can be found in ~/.config/fontctrl/fonts/.

-

Secondly, if a font is on the system, it can be really really difficult to keep track of it. After all, you probably have many many fonts, so good luck finding and removing the fonts you don't use. fontctrl fonts are not truly installed unless they're enabled similar to something like eselect.

-

After a fontctrl font is installed, it will be enabled. Enabled really just means symlinked from the */fontctrl/fonts/ directory to the actual font directory. This means the font is just stored locally in the fontctrl/fonts folder without being available to the system unless enabled. This allows fonts to easily be managed.

-

What makes fontctrl special is that it leaves the manually installed fonts and fonts installed using a package manager separate and does not even touch them. fontctrl only manages its own fonts. This keeps your system clean, as fontctrl will not conflict with another font manager.

-

Finally I should add that fontctrl is written in less than 200 lines of code, which makes it stable and less likely to fail. No features other than the base features are planned in order to keep the tool as stable as possible and it already does more than most people will need anyway from a minimal font manager.

-

If you want to try fontctrl for yourself, you can find more information about it here. Gentoo ebuild should be complete soon! Expect a mpm package in the near future as well. Thanks for reading, have a good day!

-
- - - diff --git a/articles/post29.php b/articles/post29.php deleted file mode 100644 index 2a38094..0000000 --- a/articles/post29.php +++ /dev/null @@ -1,32 +0,0 @@ - - - - -RIP in peace rchat (and releasing its replacement) - - - - - - -
-

RIP in peace rchat (and releasing its replacement)

-

2022-09-21

-

As the title says, I am going to stop developing rchat. I will be accepting pull requests and issues but I am not going to be contributing code to it anymore. It isn't all sad, but the reason for this is because of rautafarmi. rautafarmi recently decided to switch over from the old, crusty messages.txt method to using JSON. This meant rchat would have to be completely rewritten to use this new API, because it was not designed with it in mind.

-

Which is why, I am announcing its replacement named 'iron'.

-

iron is a fork of rchat but heavily trimmed down, with a clean codebase, much more suckless in design and of course, makes use of the new rautafarmi API. This means it isn't compatible with the older messages.txt method, but I hope instances migrate over to the new JSON API instead.

-

iron, unlike rchat also fixes many bugs. In rchat for example, if you disconnect from the internet while its running, rchat will print a bunch of crap on the screen. iron checks if the user is connected to the internet before it attempts to draw anything on the screen and, of course fails if the instance cannot be connected to.

-

Like rchat though, iron only comes with the bare minimum in terms of features. For example image sending support is not in it by default, there is a separate patch for it. iron patches can be downloaded and applied and they will extend the feature set of iron. The idea is, give the user a clean, stable base that they can build on top of.

-

This is where rchat failed, eventually it got too many features. iron doesn't have auto-updating, it doesn't have image integration, no link opener, no :news, no :changelog and no :help commands. iron only has the bare minimum necessary to send messages and recieve messages by default. It is up to the user to add more features through patches. He only has to apply what he actually uses.

-

Because of this philosophy, it is possible to keep iron stable, and alive without constantly pushing bloat to its codebase, requiring even more updates to fix the bugs created.

-

Another note I want to add is that iron no longer has a default instance. This keeps the users secure, because if the default instance gets compromised, the default build of iron is not going to compromise its users.

-

As of writing this blog post, all rchat patches have been ported over to iron, with additional patches being created. Anyone is allowed to contribute patches that others can apply, as long as they're licensed under the same license as the iron project itself (GNU GPLv3).

-

Finally, it should be noted that as of writing this post, the only official instance is the official instance, rautafarmi. If you are using an older instance, ask them to migrate over to the new instance, or keep using the older rchat. I will accept pull requests and issues on rchat for this reason. rchat should be stable enough for regular usage though!

-

If you want to try iron, you can download it here and there should be a Gentoo ebuild soon. As the page says, to install iron, clone the repository, cd into it and run make install.

-

That is it for this blog post, have a good day!

-
- - - diff --git a/articles/post30.php b/articles/post30.php deleted file mode 100644 index 6d724f6..0000000 --- a/articles/post30.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - -I HATE NONFREE SOFTWARE (install gnu icecat) - - - - - - -
-

I HATE NONFREE SOFTWARE (install gnu icecat)

-

2022-09-23

-

As you've read from the blog post title, I hate nonfree software like anyone with a brain should. Problem is, most people don't have a brain. But to fight back against nonfree software I have decided to move over to the 100% free/libre software web browser, GNU IceCat!

-

But what makes GNU IceCat special, and why should you use it? Well, truth is we all should use it, we just can't all use it. This is because GNU IceCat blocks all nonfree JavaScript.

-

IceCat blocks nonfree JavaScript because it allows the programmer to hide malicious features in the code and because it is obfuscated, even developers will struggle to read the code and understand what it does. Reading obfuscated JavaScript is like reading paper that has gone through a paper shredder - it doesn't work.

-

Tech companies take advantage of this fact to hide spyware and other tracking in their code. After all, a normie can't read and understand JavaScript code anyway, what are the chances that they will find out what antifeatures the software has?

-

To fix this problem, a Mozilla Firefox extension was developed named 'LibreJS'. It checks all JavaScript in a HTML document for a license. If one cannot be found, it will be treated as nonfree and blocked by the extension. This is all done before the website loads so no spyware has time to load on your system.

-

GNU IceCat takes this extension, plus adds some fixes caused by missing JavaScript, turns off telemetry (spyware), hardens security and adds some extra extensions. This makes it a bit more usable in comparison to installing Firefox and the extension with nothing else added. It also makes it more secure, because telemetry is disabled and it has been hardened because let's face it, Firefox has terrible default settings, especially for privacy.

-

This means, as long as no security settings have been changed, IceCat is one of the best browsers for security and privacy. LibreWolf may have slightly better security, however LibreWolf also doesn't come with LibreJS and has telemetry on by default, just like Firefox so it's really not worth using, you might as well just be using regular Firefox.

-

Moving over is not going to be easy, because of the way the modern web works, however I hope that I will be able to use the internet reasonably well, even while blocking nonfree JavaScript. Thank you for reading, and have a good day!

-
- - - diff --git a/articles/post31.php b/articles/post31.php deleted file mode 100644 index 22d400c..0000000 --- a/articles/post31.php +++ /dev/null @@ -1,41 +0,0 @@ - - - - -Please give me suggestions... - - - - - - -
-

Please give me suggestions...

-

2022-10-10

-

This might actually be my last blog post.. sort of. Now that I have your valuable attention, please read the rest of the blog post!

-

So, a few days ago I started working on a website redesign. However I quickly realized that it was more work than it was worth. So instead, I decided that it would be easier to straight up start from scratch. No, not completely from scratch, that would be ridiculously time consuming.

-

However I decided that it would be easier to create the HTML manually, from scratch and then copy over the text (such as blog posts) from the older page.

-

Anyways, let's get to the point of this blog post which is, I need suggestions regarding the redesign. Anything. What should I implement, what kind of design should I go for? This time, I am able to use PHP for the header, which I will likely end up doing however as always, speedie.site will stay as an anti-JavaScript website and as such, I am not going to add a single line of it even if it makes my website look nicer.

-

Here are some ideas I've got myself:

- -

As for web design, I don't really know what I want to do yet. Will likely go for a minimal design though, as minimalism tends to hide the flaws of not using JavaScript fairly well!

-

If you want to give me suggestions, you can join my IRC channel (Libera.chat network, #ff or #ststid'kwtn), or you can >send me an email. That's it for this blog post, your suggestions are appreciated, thank you for reading and have a good day people!

-
- - - diff --git a/articles/post32.php b/articles/post32.php deleted file mode 100644 index 8de043e..0000000 --- a/articles/post32.php +++ /dev/null @@ -1,54 +0,0 @@ - - - - -Forwarder Factory is over. (Please read the blog post) - - - - - - -
-

Forwarder Factory is over. (Please read the blog post)

-

2022-10-26

-

So let's stop wasting time, very important (but not good) blog post today. In short, Forwarder Factory is done, it's over. Now, so I can get this blog post out quickly, I am simply going to repost the huge and last Discord message I sent in the #announcements channel in its entirety. I know I said I wasn't going to make another blog post before the redesign but I need to get this out.

-

Original post: "So.. I've known this day would come for a very long time and unfortunately, today is that day! In the end, Forwarder Factory is (finally) over. I want to take some time into writing an announcement for you so that you're not lost. If you even remotely support me, please read the entire thing!

-

Before you start screaming "But what about preservation", note that the GitHub repositories will stay up, along with the Forwarder Factory organization. The YouTube channel will also stay up, however I will be removing the invite for the Discord server and replacing it with a link to a direct download. All the GitHub content is going to be mirrored to my Codeberg (speedie), and will get its own repository. I suggest you fork either the Codeberg or GitHub repositories to make sure they stay up if I decide to one day delete them, or if GitHub thinks I am breaking the terms of service (it is a Microsoft product we're talking about).

-

Myself and my staff have been thinking about and debating this for a very long time, but I can no longer take the daily conflicts and other maintainence issues that come with owning a server/IRC channel like this. Yes, I could in theory transfer ownership but the FF name has already been through way too much so I don't feel like giving someone else responsibility for a mess I created is fair. So the goal here is to eventually archive this channel and Discord server.

-

Recently (about an hour ago as of posting this), the server suffered yet another conflict, specifically about moderation. While this is not the direct cause, I would consider it the final straw as I have been thinking about leaving the internet/ending the server and IRC channel for a very long time now, months actually.

-

I want you to know that this is not the fault of any members here. And if it must be then it is every staff members' fault. I should take most of the blame but it is a waste to dedicate my last announcement here to that. To be honest though, I've been expecting this to happen for a very long time as I said earlier and the reason is fairly obvious looking back.

-

This server has been through a lot of drama, has had staff joining and leaving, raids and more over the last 1.5 years or so that it has existed for. For example:

- -

The last one, #based-general is in my eyes the root cause of this. What I now call "the #based-general mentality" which is a term I just invented while writing this basically spread to the rest of the server. The biggest issue however, is how I am not a good leader. It is this fact and lack of moderation by myself that caused this.

-

First of all, I am very sorry for potentially taking away your (definitely not) favorite place to talk. However I no longer think I should be the one leading the Forwarder Factory project and as such, I would like you to go to a better community that is focused on what it should be; the Nintendo Wii console and modding it.

- -

Again, all Wii repositories will stay up. Any Discord specific content is also going to be uploaded to these repositories to make sure nothing gets lost. That's what we tried to prevent in the beginning, right?

-

Either way, with that being said, if you'd like to keep up with me and/or my projects, I have a website at speedie.site where I post the current information. In fact I may post this on my website too! As for the staff members here, simply ask them!

-

I would like to give a big thank you to:

- -

..and everyone who watched one of my videos, tried one of my projects, installed one of my forwarders or joined the Forwarder Factory Discord server/IRC channel. You guys rock and we will miss you a lot.

-

I would also like to apologize to Domzuq for joking around with his IP and I would also like to apologize to bloodythorn and the r/WiiHacks community for letting them down (the server invite is/was in #affiliates).

-

I personally have very mixed feelings about this, however I feel like it is the right thing to do. Remember; all good things eventually end. The end of Forwarder Factory is today! If you have any questions about what is going to happen, you can DM me on Discord or /query me on IRC. I am going to be somewhat active on Discord until the end from now on to make sure everyone gets a chance to say something to me!

-

Thank you for everything, everyone!"

-

Yes, thank you everyone for the support, I appreciate it.

-
- - - diff --git a/articles/post33.php b/articles/post33.php deleted file mode 100644 index bf4fb33..0000000 --- a/articles/post33.php +++ /dev/null @@ -1,53 +0,0 @@ - - - - -Why I don't support RiiConnect24. - - - - - - -
-

Why I don't support RiiConnect24.

-

2022-05-20

-

As you may be familiar with if you've been following me for a while, I usually cover free software and/or minimalism. Today however, it's going to be a little different. This time it's Nintendo Wii related. If you're only here for free software, you can just skip this post but for people who are a part of Forwarder Factory or simply found my post elsewhere, this is probably worth the read.

-

For those who aren't into Wii but still wanna follow along for.. some reason, RiiConnect24 is a team of people behind Wii restoration, preservation and other popular projects. This blog post of mine explains why I'm against them and dislike their actions.

-

Disclaimer

-

I would also like to add, just in case this blog post of mine becomes remotely popular, please do NOT go ahead and hate on RiiConnect24. Despite the ethical flaws that will be shown, they really do not deserve it and you're not helping me by doing so. Please DO contact them and try to help them fix the mentioned issues however. Despite the claims I'm about to make and the facts, RiiConnect24 is behind great projects like the revived Nintendo Channels but this does NOT allow them to violate free software copyleft licenses among other things.

-

RiiConnect24 is not what it seems. Most Nintendo Wii hackers sort of look up to the RiiConnect24 team and why not? They're the face of many modern Wii projects such as the revived official Nintendo channels, WiiMod Lite, and the 'wii.guide' website which at first seems fairly innocent. In fact, I've had that exact same opinion on them for a long time. I simply saw them as 'modern' Wii hackers.

-

Violating the GNU General Public License v2

-

This was never a big issue (well it is but no one actually noticed) but one RC24 project called 'WiiMod Lite' violates the GNU GPLv2 license. Many months ago, an Issue was created on the GitHub by user jornmann named 'Potential GPLv2 License Violation'.

-

As you can probably guess, WiiMod Lite violates the GNU GPLv2 license of WiiMod Lite which is based on Yet Another Wad Manager Mod which is based on WAD Manager 1.7. Of course, waninkoko chose to license his software, WAD Manager (1.7) under GPLv2..

-

TLDR; If a project licensed under the GPLv2 license is forked, the fork cannot have its license changed. This means a fork can also not be proprietary. This is the part WiiMod Lite violates. No matter what you think about non-free software, this is not okay and the original author of WiiMod Lite clearly picked this license because they are (as good people should be) against proprietary software.

-
jornmann: GPLv2 requires the programs source to be disclosed and the license to be the same (GPLv2). WML is not licensed under GPLv2, and is proprietary. This is why it violates the license.
-
Artuto: Well we are not the original author nor have the source code or even the ability to relicense ¯_(ツ)_/¯.
-
jornmann: Then, as I've said before, contact the original author.
-
larsenv: We've tried to get ahold of the original author (who is Chinese) to no avail. I even asked someone from China to help contact them on the forum that they visit (tvgzone), but they couldn't register because they couldn't get a confirmation email for their account. I wanted the source code, but it's not my fault that they didn't share the source code.
-
jornmann: Well, that doesn't change the fact that you are still in violation of the GPLv2 license.
-
Artuto: There is nothing we can do, we cannot just magically generate the source code.
-

I think it's pretty clear what they're doing. They're trying to repost this old but according to them 'great' WAD manager while POSSIBLY knowing that the developer isn't gonna care if they don't follow the license. And since the developer of the software is no longer around, RiiConnect gets ALL the credit because of course they uploaded the binary to their GitHub. Are you getting it yet?

-

Finally, Their excuse for doing this is essentially 'we couldn't find the source code and can therefore do whatever we want with this project'. Not having source code is not an excuse and if you don't have the source code, you shouldn't be recommending it. Don't you think it's ironic how RiiConnect is all about using modern software that's actively being maintained yet they recommend a WAD manager which hasn't and won't be updated in years. In fact, looking at the closed Issues for the RC24 WML repo, you can see most issues were closed with a 'We or anyone can't do X because the source code is missing' notice.

-

wii.guide is very biased

-

Yep, and it doesn't stop there because RiiConnect24 also owns and maintains wii.guide which is the guide recommended by nearly everyone in the modern Nintendo Wii Homebrew/hacking scene.

-

I really dislike guides like this becoming popular because sure, it does mean there's one guide that you can rely on that will be updated but it also means that you can get a lot of people to use certain software for any reason. This is exactly what has happened with WiiMod Lite. The only reason I can think of as for why people use WiiMod Lite is that it's recommended by the guide and most new people read wii.guide anyway.

-

Since I hacked my Wii before wii.guide was even a thing, I didn't even know this WAD manager existed before I actually read wii.guide years after hacking Wii consoles. I guess saying this is also sort of biased because it's my own experience however my point is that most people wouldn't be using WiiMod Lite if wii.guide wasn't recommending it.

-

Now, before you think I'm just 'hating' to hate, I would like to mention that wii.guide existing is great. No longer do users have to worry about bricking their Wii because of a guide that hasn't been updated in 12 years telling you to install 20 cool awesome wads w/o Priiloader/BootMii@Boot2 but I wish wii.guide was less biased and offered alternatives to THEIR software so for example YAWWM instead of WiiMod Lite.

-

If all they did was recommend RiiConnect24, I wouldn't mind because there really is no alternative to the RC24 services as of 2022.

-

Conclusion

-

So, after all of that ranting, what do I actually think of RiiConnect24?

-

Well, I really like what RiiConnect is doing in terms of preservation and keeping Nintendo services up and running. This has given you a lot of respect among Wii users including myself. The problem is that this still doesn't allow you to completely ignore a license. It doesn't matter if the developer of X software is gone. If you don't have the source code, you're violating the license and should therefore not continue hosting X software.

-

As for being biased, I can sort of excuse that, even though it is a problem because they can get anyone to use anything.

-

However, wii.guide is still the only Wii guide worth using so really, I'd love to see it get improved.

-

Finally, do I hate RiiConnect24? No, I believe the people who are working on their projects simply want the best for us however like I said, they've been doing some sketchy stuff so that's what this post was made for.

-

I would like to thank you for reading this post,

-

If you wanna make a change, consider sharing this post with the RiiConnect24 people so that they can improve the problems I've discussed. If you have any more problems with RiiConnect24 and/or the people behind it that you'd like to share then please do so by sending me an email.

-

If you wanna support me and my work, consider donating anonymously here.

-

Thank you for reading and have a super based day!

-
- - - diff --git a/articles/post34.php b/articles/post34.php deleted file mode 100644 index dba898f..0000000 --- a/articles/post34.php +++ /dev/null @@ -1,46 +0,0 @@ - - - - -We're back up better than ever! (feat. OpenBaSeD) - - - - - - -
-

We're back up better than ever! (feat. OpenBaSeD)

-

2022-11-25

-

We're back!

-

We're back up better than ever! Right when the canonicucks thought I was gone for good, I rise from my grave and bring you a new website and blog post. Okay, okay on a serious note I have some very important news to share with the people who (still) follow my blog.

-

Solving the existing problem with speedie.site

-

Maintaining the speedie.site website has been a struggle and it only gets worse with every blog post and page I create.

-

I thought about my alternatives for solving this or at least improving on it, things like using Markdown, writing a simple shell script to append text or even stupid static site generators, but in the end I decided to go with PHP. And it makes sense, PHP is a solid option and has been around for years. -

It has a major flaw in what I am trying to accomplish with it and that is server-side code that the user can't see. Of course the source code for the PHP is public and available for everyone.

-

I have and will continue to publish all changes made to the PHP to the Codeberg repository but you have no way to verify that the code is identical to what is running on the server. I am not sure if there is any way to prove this to the users of my website but if there is, let me know and I'll gladly provide.

-

This is much more convenient than manually editing every single HTML document on my website any time I want to change a single character.

-

Hosting

-

GitHub Pages which I used to use up until yesterday has one flaw which would stop this plan right away; it does not support running PHP in any way. I presume this is for ""Security"" reasons, like what if some script kiddy runs dangerous code on our servers? Either way, I had to stop using Pages for this to work out.

-

My friend offered to host my website on her VPS and for a while I accepted but because I felt bad for wasting her bandwidth and space and because it's not as safe to rely on others, I decided to get my own VPS instead.. It's really cheap and while I *do* plan on self-hosting eventually (need to build a computer to host on), I felt this was a good solution.

-

I installed OpenBSD on it because it is a great system for building secure servers but importantly it uses LibreSSL which was something I really wanted for this website.

-

Issues

-

OpenBSD works a little differently than the GNU/Linux I am used to so this took a bit of work to figure out. Most of my issues were PHP related because it's much harder to set up on BSD.

-

While the website still has a few flaws that I plan on fixing very soon (https://speedie.site/projects doesn't lead to project-list.php and instead results in an 'Access Denied.' from Apache), the website seems to be work fine.

-

Website rewrite

-

So, let's talk about the website itself.

-

First of all, just take a look around. The website has been rewritten from scratch, this time using PHP for the header and footer. This allows changes to be easily made to the header for every single document (there were a lot of them) saving time.

-

As for other changes, blog posts and text guides are now in the articles/ directory. This was done to keep the root less cluttered which is important when you are going to be hacking on the website for a while. Images are still in img/, CSS is still in css/ and the header/footer is in the php/ directory and projects have been moved into the projects/ directory. I may do more with PHP in the future but right now it is only being used to include the header and footer.

-

I also decided to archive blog post 1 through 10 due to them being either irrelevant, misleading or just bad to read. You can still read them but they have a little warning attached.

-

RSS that sucks less

-

I finally spent the 10 minutes necessary to make my RSS feed valid. Readers like Newsboat now display the right time and date which was not the case previously. It's a small thing, but equally small is the time it takes to fix the problem I had created.

-

Wen replace domain name?

-

Not sure yet, if Unfreenom decides to take away my .gq domain name I am likely going to buy a proper domain that doesn't do stupid stuff like this. I won't do it otherwise due to the pain of switching domains (and changing GitHub name once again).

-

Questions?

-

If you have any questions about what has been going on, please consider emailing me. I don't bite but respect should be earned.

-
- - - diff --git a/articles/post35.php b/articles/post35.php deleted file mode 100644 index 5c426bb..0000000 --- a/articles/post35.php +++ /dev/null @@ -1,35 +0,0 @@ - - - - -speedwm 1.5: It's still speedwm. - - - - - - -
-

speedwm 1.5: It's still speedwm.

-

2022-11-28

-

Not this again..

- preview image -

I know what you might be thinking but eh, this happens weekly, might as well get it over with.

-

Decided to release speedwm 1.5 today and in my opinion, it makes all previous versions irrelevant, not because this one is so great in terms of features but because it's so much faster.

-

Master, what changed then?

-

Tired me at 10 PM joke out of the way, what changed, what made 1.5 worth the release?

-

In my spare time I had waiting for the bus, among other things I decided to rewrite all of my status modules. I also wanted to see how many if statements I could get rid of. Answer? All of them. None of my modules have a single if statement in them now. I also cut the line count for most of them down by at least half, which is a good thing for readability, because fewer lines means fewer possible mistakes and fewer possible bugs to destroy the software.

-

I would also look like a hypocrite if I was promoting well written software while having terrible code myself. Pretty much all commits after the 1.4 release have been bug fixes. ..Except a few.

-

One important thing to note is that speedwm_run is no longer used, and speedwmrc is not used either. If you want a speedwm config file, copy docs/example.Xresources to wherever you want it and add xrdb /path/to/that/file to ~/.config/speedwm/autostart.sh. To start speedwm, you simply run startx /usr/bin/speedwm or add speedwm to your .xinitrc. Those of you using a display manager already know what to do.

-

Get this slow trash off my system.

-

From that h3 I'm sure you know where this is going. speedwm 1.5 removes the old stellar xsetroot (well, now speedwm -s ) status script and replaces it with a partially integrated fork of dwmblocks. dwmblocks is a lot faster than the status script I was using previously. Because it still uses status modules though, you can still configure it in shell so no extra skill is necessary.

-

The old script also didn't allow updating each module individually meaning you're going to constantly waste your resources on reloading status modules that don't need to be reloaded all that often. The new status (written in C) solves this because it allows you to specify how often each module gets updated, and it can also be updated manually by sending a signal.

-

That's all, glowies.

-

That's all I have to provide for today. I am tired and don't feel like writing a proper blog post, but I will hopefully have something worth reading out tomorrow.

-

Have a good day, or night.

-
- - - diff --git a/articles/post36.php b/articles/post36.php deleted file mode 100644 index 3445120..0000000 --- a/articles/post36.php +++ /dev/null @@ -1,49 +0,0 @@ - - - - -I use Chromium based browsers again.. (How to lose your followers in less than 5 minutes) - - - - - - -
-

I use Chromium based browsers again. (How to lose your followers in less than 5 minutes)

-

2022-11-30

-

Think before you talk, or you end up looking like an idiot like me.

-

If you've been following my blog for a while, you might remember an old blog post of mine titled 'Everything I want to use is Chromium'. Like the title says, In the blog post I complain about every web browser using the same web engine; Chromium. In the end I said something that I would later regret though, because of course I did.

-

"To contribute to this, I've decided to BAN myself from ever touching anything based on Chromium or Electron."

-

While I have partially held that promise (I haven't tried Electron and I have no plans to do so), I am now back on Chromium based web browsers. Feel free to unsubscribe from my feed now.

-

With that said..

-

Now that I successfully managed to lose my last readers, I am gonna continue talking to myself in this blog post. Why did I start using Chromium again?

-

It's because Firefox sucks. That's the answer. Very surprising isn't it? Okay, okay here's the thing. If the year was 2010, I would be sitting here shilling Mozilla and everything they have ever produced because they truly used to be great. I have been a fan of Firefox if you will for years. They're one of the only (sort of) mainstream free software web browsers.

-

But lately they've been going down a dark path. From the privacy issues, to the Facebook partnership, to Google being the default search engine, to their controversial blog posts (I know a thing or two about that) and many more.

-

We get it, why is Firefox no longer usable?

-

Long story short, Mozilla Firefox is riddled with bugs, making it about as stable as alpha tier software.. that has existed for almost 20 years. First annoying issue: Firefox being unable to open more than one new window at one time. As Firefox reached version 100, it stopped properly opening windows. I use a lot of windows and few tabs, so this really impacted my usage of it. As you know I use a tiling window manager and I liked being able to put one Firefox window on another tag and another on my current tag. This was useful for writing the website you're currently reading.

-

With my mouth filled with the bad taste of the bug I just mentioned, it doesn't help that the web is getting increasingly harder to use with the Gecko web engine. Piped and Invidious? Page crashes really often. searx? Loads much slower than on Chromium, and this is not even a JavaScript heavy website in the first place so there is no excuse for the slowness.

-

The final straw for me was Firefox taking what feels like years to start up. I would press my keybind to start up Firefox and sometimes wait up to 20 seconds for it to start. It was all up to luck, really. As if it makes it better, when it doesn't start, you'll assume you didn't press the key or something so you'll do it again, and again.. and again. When Firefox finally starts up, you'll have 20 different instances of Firefox and you'll be using up all your RAM and CPU. Not ideal.

-

Ever since I experienced these issues, I went looking for a better web browser and eventually said, 'You know what, I don't care anymore I'll try this out.'.

-

Chromium.. doesn't suck? WHAT?

-

I ended up trying Chromium (specifically ungoogled-chromium but it's nearly identical) and it only ended up being the fastest, most stable web browser I've ever used. It just works, without the slowness, without the horrible bugs, without the 20 seconds startup time, without searx and piped not loading pages properly. It all just worked, and it worked great.

-

Realizing I just couldn't pass up the opportunity to switch to a web browser that doesn't fail me on a daily basis, I cut my losses, realized I eventually had to write this blog post and removed Firefox from my system.

-

Is Chromium perfect? Far from it. For one, the Manifest v3 garbage is going to be a major blow to extensions in Chromium. Plus, Chromium is nearly impossible to customize in any meaningful way. Sure, you can change the colors and stuff like that but good luck doing more advanced things. To my knowledge it's not even possible to remove the account icon from the bar, which is why Chromium is the GNOME of web browsers. (Except, GNOME actually sucks)

-

To be fair..

-

I never said Chromium was a bad web browser. I didn't really dislike Chromium for that reason. The reason I refused to use Chromium was because it is slowly becoming the one and only web engine. Slowly, all other web engines are becoming more and more irrelevant. This is partially why Firefox sucks so bad. But I am done with Firefox constantly screwing me over.

-

Qutebrowser

-

A week or so after I started using Chromium, I realized I could now try Qutebrowser, which is Chromium based but similar to browsers like Vimb in that it uses Vim keybinds for navigation. I ended up enjoying this web browser a lot and while it is slower than Chromium, it is significantly faster than Firefox and is now my web browser of choice. It is written in Python which probably contributes to that extra slowness over Chromium, it's not really noticeable during usage but you will notice it when you start it up.

-

It also has no extensions just like Vimb and suckless surf and all of these browsers, but it's really /comfy/ to use, especially for someone used to Vim.

-

But.. but.. what about webkit?

-

Not gonna go into the Webkit engine here too much but it is even less usable than Firefox in pretty much every way. Sure, web browsers like Surf that use it start up nearly instantly but it has so many flaws and tends to crash when even a slight bit of JavaScript is in the website. And as we all know, it's really difficult to avoid JavaScript in the year 2022.

-

Even loading basic websites, like searx, and even 4chan, a website which has barely been updated since 2003, both surf and vimb tend to crash almost instantly. I tried with a vanilla build of surf as well and still crashes. Because of this issue, and media playback barely working if at all, webkit is not the engine for me.

-

So.. conclusion?

-

I know you're probably expecting a 'I switched back to Windows' or 'I work at Apple' blog post next but.. yeah, no that's not gonna happen. I still use exclusively free software and that's not changing. Ultimately, Firefox has gotten a lot worse since I made that initial blog post, so I gave in and started using Chromium.

-

Thank you for reading, I will now await my check in the mail from Google Inc, see you next time where I install Windows on my ThinkPad and switch to VS Code and Microsoft Edge.

- -
- - - diff --git a/articles/post37.php b/articles/post37.php deleted file mode 100644 index b4d32b3..0000000 --- a/articles/post37.php +++ /dev/null @@ -1,54 +0,0 @@ - - - - -How I got into GNU/Linux - - - - - - -
-

How I got into GNU/Linux

-

2022-12-13

-

I AM FINALLY FREE! Time to unfree myself.

-

I am back. I finally got released from prison after Google put me there and forced me to write a blog post..

-

Today I want to talk about getting into GNU/Linux and free software, how I got into it and how you can get into it yourself. But because my "started using GNU/Linux" story is so short, I'm gonna also talk about how I got into certain software like dwm and Gentoo, since normies tend to call this stuff difficult.

-

My first encounter with GNU/Linux

-

My first encounter with the GNU/Linux operating system was in 2011 when I found out about this new "fancy" operating system called Ubuntu GNU/Linux. People like myself reading this blog post right now might say "DOnT yOU hATe UbUnTU?!?!?" but back then, it was very different from what it is now.

-

Back then, it was a fairly nice system. I didn't end up sticking with it as you'll read later, because it wasn't able to run most of my software. For this reason, I went back to Windows 7 and forgot about Ubuntu and the wonders of GNU/Linux and free software.

-

Either way I kept using Ubuntu for a few months (not sure why I didn't stick with it after that) and used the absolute garbage that is Wine to attempt to emulate the Windows experience I was familiar with instead of attempting to learn new software. Probably the most common mistake any new user makes.

-

Most easy distros are terrible

-

In 2017 or so I went back to trying out various GNU/Linux distributions like Elementary OS and Manjaro, all of which are absolute garbage distros that barely work. While it may be different now, I can't help but stop and ask; Why are all "easy" distros so bad?

-

The answer is going to be different depending on who you ask but since you're reading my blog, I'll answer it. It's because they try to make the wonders of GNU/Linux something that it isn't. They try to turn it into a free version of Windows, rather than making 'the ultimate OS'.

-

This stupid direction made all easy distros end up using this stupid software that takes the bad from Windows and nothing good and what you get is an absolute mess which is going to break within a month.

-

Long story short, lasted a few weeks and then went back to Windows.

-

Freedom is hard to resist

-

However, freedom was hard to resist so I kept trying out various distributions in my free time but never ended up finding anything I actually liked. Eventually I got sick and tired of Windows doing stupid Windows-y things and installed Ubuntu.

-

After all, it had been years since I last used it (2011) but maybe software support has improved, I thought. Yes, software support had improved but everything else SUCKS. It was slow, had terrible default applications, grub broke all the time, kernel was missing, X doesn't even start properly, and many many more issues.

-

I then later reinstalled Ubuntu in the hopes that I had messed something up. User error is normal, I thought. After that, I didn't really encounter any more issues and I was able to do most things just fine on my computer. I still don't know why it just NOW works properly.

-

After a while I started learning to write basic shell scripts, because that's what you do when you have free time and want to learn how to use your computer properly. It's a great way to learn your system.

-

While watching some bad YouTube guides on the basics of shell scripting, I saw this one guy with a really cool desktop. "WHAT.. WhAT?!?!? IT TILES???? WAOW". Through a simple search and some reading on window managers, I installed i3-gaps on my then Ubuntu system and switched to using it. I really started to like customizing my system, and I loved efficient, quick keybinds for everything.

-

Distro that sucks less

-

Ubuntu was of course holding me back from the customization I wanted to do, and had thousands of packages even after removing all the GNOME garbage. I had already been experimenting with Arch for a while on my old iMac.

-

Out of boredom, one day I decided to install Gentoo in a virtual machine. It was more as a challenge more than anything, because as I understood it, this distribution was difficult to use and install. (Now that's false, but that's another issue)

-

Eventually, when Ubuntu yet again broke, I decided to install Gentoo on my system. It took a while due to the weak processor I used to have.

-

suckless software

-

Around this time, I was told about suckless software; specifically dwm. It basically looked like i3 but more convenient to use. It also seemed like a great window manager because it was configured through source code meaning it's very extensible and hackable.

-

So for my new Gentoo system, I installed dwm instead of i3 and started configuring it. You can actually still use my dwm build from then, it can be found here. This made my computer feel so much better and so much more usable and extensible. I cannot recommend learning software like this enough.

-

Then to now.

-

Not much has changed. Sure, I've switched to/from software but I'm still learning about the system and software I use. There really is no end to learning about technology and software. It keeps going as long as you're interested in learning further.

-

How can I get into it too?

-

My number one tip for people trying to get into GNU/Linux is this; don't give up too early. Expect to face challenges but be smart and attempt to work around them.

-

And as I mentioned above, instead of trying to run your spyware software, try to run free software compatible with GNU/Linux rather than the Windows-only software you're already running.

-

Finally, don't expect to learn everything instantly. You learn as you go, and you learn from your mistakes.

-

The most generic conclusion in history

-

I am now a Gentoo GNU/Linux user. Overall, it's been a great experience and I love the freedom and customization I can do to my desktop. I'm able to make it anything I can imagine. It truly is great and it's the peak of computing; well, other than writing your own operating system.

-

Thank you for reading the blog post, have a good day!

-
- - - diff --git a/articles/post38.php b/articles/post38.php deleted file mode 100644 index 3527689..0000000 --- a/articles/post38.php +++ /dev/null @@ -1,56 +0,0 @@ - - - - -I WILL make music great again. (My next project) - - - - - - -
-

I WILL make music great again. (My next project)

-

2022-12-20

-

Finally something worth your time?

-

Time for something a little different than usual. Today I'm going to talk about my next project that I am working on as we speak. It usually starts with 'boo this program sucks, let's write something that does what I need it to do better than the current options and this time, it's no exception.

-

As you know, I've been working rather heavily on my dwm build; speedwm. I've been trying to iron out bugs with it and generally make it the window manager (or computer setup in general) of my dreams. After I reached 800 commits just a few days on the new speedwm repository alone, not to mention the many more on the old repositories, which adds up to over a thousand commits, I realized that I am trying to improve something that doesn't really desperately need improvement.

-

Now that I'm fairly happy with it, I am going to start a new project. I might work slowly on speedwm, and hope to have a 1.9 release out soon but I don't plan on making any more massive changes to it. So as usual when it's new project time, what happens is I think of a piece of software that sucks and then I try to make something that fixes the flaws. What is it this time?

-

Make music great again

-

Yes, you heard me right. I am going to write a music player. Or rather a mpd frontend, because it would be stupid to reimplement something that already works well, right?

-

Now, I am listening to music through cmus as I am writing this blog post for you, and I have to say it's generally a great music player. It's light, fast, Vim-like and fairly polished and clean. Unlike the mocp I was using earlier, it has a UI more like.. you know, a music player than a file manager which is one of the reasons why I much, much prefer cmus. So why does this need change then?

-

cmus is not built for window managers

-

Yeah, I said it. One of the problems with cmus is how difficult it is to manage it through the command-line. There is cmus-remote, however even with this you often have to use lots of slow awk commands to get the format you want.

-

I plan on solving this by adding window manager/status friendly syntax which allows the user to specify a format, no slow awks or seds in your status script.

-

Lack of extensibility

-

None of the music players/mpd frontends I've looked at are extensible enough for my taste. I want to be able to make it extremely minimal or command-line Spotify without any delay or external programs.

-

It doesn't help that cmus and a lot of other music players don't seem to be maintained very much. Most of them seem to be written for TTY users, and don't have a lot of fancy features. This is not great when you want a light (but feature rich) music experience.

-

I plan to solve this by keeping the base small and clean, as well as a very well documented codebase unlike suckless software. While I for the most part like their philosophy, I am not a fan of how they refuse to add any meaningful comments to their code.

-

Cool planned features

-

None of these have been implemented yet but I might end up implementing them. Some as modules, some built into it.

- -

Ideas

-

If you have any ideas for this project, please consider emailing me it. I want to make this project as good as it can be.

-

Naming?

-

I have no idea what to name this mpd frontend, if you have any suggestions feel free to send me a suggestion.

-

End.

-

Going to end the blog post here as I've already rambled on and on about how music players suck and what I want it to do. Thank you for reading and have a great rest of your day!

-
- - - diff --git a/articles/post39.php b/articles/post39.php deleted file mode 100644 index 1918994..0000000 --- a/articles/post39.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - -Goodbye 2022.. - - - - - - -
-

Goodbye 2022..

-

2022-12-31

-

2023 is basically here and that means 2022 is over. Happy new year to everyone who follows my blog. March is going to mark 1 year since the first blog post, but there's still a good while until we reach that milestone.

-

Anyhow, I was planning on making a long blog post about 2022 and how.. mixed it was but because I had too much fun, I did not have time to finish it. I didn't really like what I had written anyway so for this year, a small blog post like this one will have to do. What a shame?

-

Nothing is really going to change as 2023 comes around. Blog posts are still going to come occasionally like normal. Either way, since I bothered to make this blog post, I might as well talk about some things that don't really deserve their own blog posts.

-

First of all, mph (the music player project I announced last blog post) is still alive, I did not cancel it like a lot of my other projects. While I had to stop working on it for a bit because I ran out of time and had to fix some critical bugs in other projects, I have implemented a basic plugin system for it now and I'm in the process of implementing basic playback.

-

Secondly, another project of mine, fontctrl got a 1.2 release recently. The release adds support for batch font installation, and can now also take stdin which is probably useful. I highly recommend you try out fontctrl if you're a user of a minimal GNU/Linux system that does not have a GUI font manager already.

-

I have also been making a few (small) changes to speedwm, mostly keybind related. There's now inset support, and it has been updated to the latest suckless commit. Documentation has also been updated and there's now a KeyPress/KeyRelease option which should fix various bugs. Finally rounded corners have been removed because they were buggy and ultimately don't look that good so I removed them. Users who want rounded corners can use picom instead which does rounded corners better than speedwm ever did. Plus it also allows rounded corners for the bar which speedwm never did.

-

speedwm-extras (separate project) was also updated slightly, specifically audioctrl and btctrl, which now work much better.

-

As for the final update, the donate page now has a Vultr referral link, which if you use it will give me $10 in credit or about 1 month of free server uptime. Feel free to use that if you want to support me and get yourself a VPS.

-

Either way, that's it for this blog post, and next blog post (in the next year) will be post number 40! Happy new year everyone, and have a good day!

-
- - - diff --git a/articles/post40.php b/articles/post40.php deleted file mode 100644 index 01717ef..0000000 --- a/articles/post40.php +++ /dev/null @@ -1,38 +0,0 @@ - - - - -Let's talk about Project 081 0.6 - - - - - - -
-

Let's talk about Project 081 0.6

-

2023-01-03

-

So.. because I keep getting questions about Project 081, even though I don't really work on it much anymore, I thought I'd make this blog post as an update on it as well as why it's taking so damn long. Also if this blog post comes across as negative, I'm sorry, it's 5 AM and I'm tired. Suck it up.

-

I will be honest here, I hate working on Project 081, and this is not because I think the project is bad, or even because its ABSOLUTELY PROPRIETARY (hopefully one day we get the source code for Tiger). It's because it's a massive pain to test it or even to create a basic image. As I mentioned in the issue on the GitHub repository, testing the project has been a challenge for multiple reasons. Here are just a few:

- -

That's not to say Project 081 0.6 is cancelled. I did say work on Project 081 ended on my page a while ago but that notice was removed after I realized that fixing this problem was fairly trivial. People have been asking me about the state of Project 081 though so clearly there is some demand for a new version.

-

For now, there's an open progress tracker for Project 081 0.6 which spawned out of this issue regarding blue screen. The goal is to eventually fix this issue and get a proper version out but before that can happen, I need to get a script or something working so that this massive waste of time can be automated. That would only leave testing, which takes a bit part of the pain away.

-

Well then, to end this blog post off, I would like to mention how I'm very surprised that Project 081 is still (somewhat) in demand. Especially since it has not been actively worked on for over 2 years now. Yeah, insane I know. Time flies when you're.. ..not having fun.

-

If you have any more issues on any hardware, consider making an issue on the p081/Project081 repository as I do not want to have to make yet another release after this if I can avoid it. Thank you for reading this and have a good day!

-
- - - diff --git a/articles/post41.php b/articles/post41.php deleted file mode 100644 index 70e8f32..0000000 --- a/articles/post41.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - -Why YouTube©️™️ doesn't recommend your videos. - - - - - - -
-

Why YouTube©️™️ doesn't recommend your videos.

-

2023-01-15

-

Now, unless you're some big channel that uploads every day or something like that, you've no doubt experienced the absolute pain that is YouTube refusing to promote your videos.

-

Even if you're someone like me who doesn't really care that much about getting views or something and just casually uses the platform once a month or something to post stuff occasionally, you've no doubt noticed that if you upload videos in a short timeframe, no matter what it's about, it's almost guaranteed to get more views than anything you just post and forget about.

-

This is just a theory but I suspect Google and YouTube wants you to constantly push out new videos every day, even if it's total crap not worth 30 seconds of your time. As you know, I tend to only upload videos once a month or less, and that's for multiple reasons.

-

Firstly, I don't have time to push out content daily about the new cool dwm patch or whatever. Not only is it not very useful for the viewer and basically acts as filler, but it's a waste of time for me as well. Secondly, YOU don't have time to watch this filler garbage content that only exists to make YouTube push your content to people's feed.

-

I think a good example of this is if you look at my Forwarder Factory channel, which is now completely dead because I have zero plans to upload anythng to it, but anyways all of the old videos were successful and got plenty of views, despite the content of the videos being mostly crap.

-

I then of course stopped uploading to it for reasons I don't need to specify and 4 months later I broke the silence a nd posted something to it. Got 487 views which is absolutely nothing in comparison to what the earlier videos got. YouTube likely refused to promote this video because I hadn't been posting consistently up until that point.

-

Of course, this isn't always the case and we don't exactly know how the YouTube algorithm works because of course it is not free as in freedom software. Some topics combined with good timing are basically view magnets. My Windows 11 sounds video got over 100,000 views just because at that time Windows 11 had just leaked and almost no one had covered the topic yet.

-

Either way this YouTube thing is really frustrating and it's one of many reasons why I think being a 'YouTube Certified™️ Content Creator™️©️' is a waste of time for people like me. Even if you get less traffic to your website or whatever, I highly recommend that you stick to free/libre ways of spreading your word whenever possible such as using the LBRY network or even better, just having your own blog and website that you have control over, or at the very least, you don't trust YouTube.

-
- - - diff --git a/articles/post42.php b/articles/post42.php deleted file mode 100644 index 4becc47..0000000 --- a/articles/post42.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - -When will I use BSD? - - - - - - -
-

When will I use BSD?

-

2023-01-17

-

So, I am considering installing BSD on my computer, specifically FreeBSD. Or maybe we should call it FreeBaSeD, whatever.

-

Now as you guys know I of course use Gentoo GNU/Linux as my desktop operating system. It's definitely my favorite distribution because it doesn't seem to have all the flaws other distros like Arch have. I haven't had many issues with Gentoo, I mean Portage is quite slow because it's written in Python but for the most part it has been really reliable and I am typing this post from Gentoo. However most other distros don't seem to be very reliable, not to mention some "recent" events are really encouraging me to switch over to a different operating system.

-

As you all know though, I use free (as in freedom)/libre software and because of this, there's no way I'd use something like Microsoft Windows or Apple macOS©️™️ again but there are many free operating systems, and of course FreeBSD is one of them. I've used OpenBSD in the past, not as a desktop operating system but I use it to host this website. It works perfectly for what I need it to do, but admittedly I'm still kind of Ubuntu user levels of familiar with the BSD operating systems.

-

Either way does this mean I'm going to switch from Gentoo to FreeBSD? Does this mean I'm no longer a Gentoo user? No, it does not, no. But why do I want to use BSD and not GNU/Linux? It's because recently the normies have taken over GNU/Linux and written mandatory garbage for it. One recent example is how Rust (the programming language) is now part of the Linux kernel. While it isn't mandatory yet, drivers and other basic stuff is probably going to be rewritten in it soon, just because the Rust programmers who have no business in the kernel development space can't even write a single line of C. There's now also other stupid software like systemd, Flatpak, Wayland and all this software that takes everything we like about GNU/Linux and throws it in the trash.

-

BSD has some of this stupid software, such as Wayland for example, but for the most part BSD seems pretty clean of the years of trash piled on top of GNU/Linux. I know I've rambled on about how GNU/Linux sucks and I haven't even made this blog post worthwhile, so for real though, why FreeBSD? Well simply, FreeBSD seems to be more like what GNU/Linux was.. you know, 15 years ago before the normies discovered it and ruined it for all of us (yes, even them). It seems to follow the UNIX philosophy much closer than GNU/Linux does these days. I should also add, the BSD community doesn't seem as horrible as the GNU/Linux community, which is of course a plus for various reasons. This may be because normies haven't found it yet, or maybe its users just want a functioning computer. Regardless, it seems like a much better place for someone like me.

-

Either way, this was just a short blog post on why I don't really like GNU/Linux, and why I may consider switching to a system with the BSD kernel. I have another one coming up very soon, as despite not being forced to make blog posts, I still want to put something up so you don't think I'm dead or something. Either way, if you have some experience with BSD, feel free to let me know if there are any huge problems with it but because I use for the most part (Still have the Intel Spyware Engine™️ sadly) free software, software support is not really a huge problem for me.

-

I feel like this post is slowly becoming filler so yeah, might as well end it.

-
- - - diff --git a/articles/post43.php b/articles/post43.php deleted file mode 100644 index 1ce3701..0000000 --- a/articles/post43.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - -speedie.site now has a wiki! - - - - - - -
-

speedie.site now has a wiki!

-

2023-01-26

-

This is just a brief blog post regarding some new somewhat important news for this website! speedie.site has received a wiki, which anyone may edit. No, this is not some bloated wiki solution, it's done using purely PHP and CSS, and articles are written in Markdown! This is great, because speedwm documentation is already written in Markdown and has been for a while. Not only that, but speedwm has it's own separate wiki, because a lot of information is speedwm related.

-

Now, I want to get speedwm 1.9 out soon, especially since it has been two full months since the last release and over 100 commits since then, but I want to move some documentation over to the speedwm specific wiki first, as I think the man page is growing very, very big. That is not great, not to mention any documentation in a tarball cannot be updated as the release has already happened. Not ideal, is it?

-

Also, a speedwm wiki was pretty much necessary at this point. While you can pull request to the speediegq repository on Codeberg, there's a lot of delay and work involved in that, when all you want to do is say, fix a simple typo or something like that. However not only can you edit existing articles written by me, but you can also create new articles if you feel like something is missing. While this is speedwm documentation, a lot of it also applies to dwm, so if you're into hacking on dwm you might want to check out the wiki!

-

As for the more general wiki, it's far, FAR from complete so far. In fact there is only one article. But I plan on slowly expanding it as time goes on. With that said, you may be wondering what wiki solution I went with. Did I write my own? What wiki solutions are there that aren't absolutely massive and terrible?

-

Of course, w2wiki. w2wiki is written purely in PHP and CSS, and articles are written in Markdown as stated previously. I have to say I really like w2wiki and I have no plans to use something different. I will say, I don't really like the default CSS, however we're not soydevs here, so I changed that to fit the theme and minimalism of the regular speedie.site website.

-

Anyways, that's just a small post for today, I have two more suckless related posts coming up relatively soon, but after that I hope to write some more classic blog posts. I have been relatively busy with real life of course, so I haven't had time to write anything proper, although I have a relatively good amount of ideas.

-

That's it for today, thank you for reading, check out the general wiki, as well as the speedwm wiki and have a nice day!

-
- - - diff --git a/articles/post44.php b/articles/post44.php deleted file mode 100644 index 5db86c8..0000000 --- a/articles/post44.php +++ /dev/null @@ -1,26 +0,0 @@ - - - - -..and a git repository (CGIT REVIEW!!!) - - - - - - -
-

..and a git repository (CGIT REVIEW!!!)

-

2023-01-28

-

I don't think it needs to be said but I've been doing some changes to this website recently. If you saw yesterday's blog post, I talked about some changes I had made, such as introducing a speedwm and general wiki to the site. I made some changes to the wiki shortly after publishing that blog post, and today I made even more changes so I think it justifies another blog post. Either way, this blog post is practically just an extension to the last one.

-

Now, why did I make these changes, and why the title which (seemingly) has nothing to do with the point of this blog post anyway? Well, you see I decided to try to set up a Git server by myself for a few reasons and that's exactly what I really want to talk about, I just think I should put the wiki changes in this post as well. First of all, I should mention that the speedwm wiki has moved to speedwm.speedie.site and the more.. general wiki has moved to wiki.speedie.site. I'm doing this because it's good practice, really. Besides, I want to be able to use projects/speedwm again if necessary. I have updated the blog post to reflect these changes of course, but just keep that in mind.

-

Alright, let's talk about cgit, which is likely why you clicked on this blog post in the first place. cgit as the name implies is a git frontend which allows you to go through commits and other nice things using your browser.. alright alright I think we all know what it is now but cgit is written in C, no not C++, Rust or any other garbage, just plain perfect C. It's also very minimal but still offers basic functionality and even some nice things like RSS feeds for commits, which I talked about in my blog post about Codeberg, which is really nice for people like myself who primarily use the internet through these feeds anyway.

-

I looked at other solutions as well, such as stagit but they all had annoying flaws which cgit didn't seem to have so I decided to attempt to host an instance of cgit. I would say it went relatively well, and it was definitely a learning experience. I don't think I've learned this much about Git in 30 minutes ever before, so I'm definitely glad I did it for that reason as well.

-

By now, you may be wondering if I'm going to leave Codeberg. I have no plans to leave Codeberg, but some of my projects are going to be moved to git.speedie.site because internet independence is always a good thing, and I like the control this gives me. As of writing this blog post, speedwm, speedwm-extras, speedwm-wiki, libspeedwm, spmenu, st and speediegq all have repositories on git.speedie.site, some more are going to be moved and the Codeberg repositories for these are going to stay as backups that will be updated around each version bump/release. Some repositories will stay on Codeberg as it's just unnecessary to move them to git.speedie.site for various reasons such as lack of quality.

-

Either way, I think that's all I have to say, next blog post is probably going to be about my computer setup in general (it's VERY different from the norm, beyond just the operating system and window manager). So yeah, check out git.speedie.site, and the wiki if you haven't already, and have a good day!

-
- - - diff --git a/articles/post45.php b/articles/post45.php deleted file mode 100644 index 116d535..0000000 --- a/articles/post45.php +++ /dev/null @@ -1,35 +0,0 @@ - - - - -speedwm 1.9 release - - - - - - -
-

speedwm 1.9 release

-

2023-02-05

-

speedwm 1.9 was released so I thought I’d write this short blog post. Yes, there is a real blog post in the works as well, in fact it’s basically complete, but I think writing this is necessary.

-

Either way, speedwm 1.9 is out now, and I want to talk about some of the changes I’ve made to it, since there are some big changes that will definitely be noticed if you just update from 1.8 to 1.9. First of all, if you just updated, you might notice that most of the keybindings have been removed. Many of the chained keybindings have been removed, because I simply wasn’t ever using them. But that’s not what you noticed, is it?

-

I removed most of the keybindings that call spawn() (the function that runs a program) because if I leave them in, people need to have all that software installed to make the keybindings functional. That’s not great, so instead of dealing with that I simply made a copy of the old mouse.h and keybinds.h and uploaded them to my dotfiles repository on Codeberg.

-

Now, of course I still use the old list of keybinds myself, so how am I going to update keybinds efficiently? Well, that’s why I added a few lines to the Makefile. If there is a keybinds.rl.h for example, it will be temporarily copied to keybinds.h and the old file will be restored after the compilation, so the original file is intact but the binary contains the keybindings from keybinds.rl.h. This behavior is not exclusive to this header but also works on bar.h, options.h, mouse.h, and status.h.

-

In other changes, dmenu is no longer a dependency for speedwm, and is no longer used. Instead, speedwm now uses spmenu, my fork of dmenu which adds some useful things like color support, a proper keybind array, many more arguments and more. This fork was created to solve compatibility issues, as spmenu has a lot of arguments that dmenu simply does not have, and dmenu does not (by default) ignore arguments it does not recognize, something it should probably do because of all the patches available for it.

-

As for bug fixes, there are a lot of them. First of all, status modules now support pango markup, which was disabled by default previously. The window swallowing functionality now updates the icon, not doing so is a dumb oversight on my end, but 1.9 fixes it. I’ve also fixed the custom layout crashing. Previously it would crash when you try to enter an S-expression due to the (bad) handling of history. Instead of using the old terrible approach we’re just running a separate shell script and parsing stdout. Much better, and because it doesn’t read a file using fgets() the possibility for crashing is much smaller. Finally, I have fixed multi-monitor crashing. It’s a shame it took this long to be noticed, but I will make sure it works properly for every release from now on. On 1.8, you can mitigate this by disabling tag previews.

-

I’ve also added a lot more documentation, although existing documentation has been shortened down. Documentation will now be found primarily on the wiki, which anyone has both read and write access to. Yes, I know this is risky but I’m using Git to back stuff up, so it should be fine even if someone is dumb enough to ruin it for everyone.

-

The update also includes a few (not a lot, but a few) new features like:

- -

Importantly though, speedwm-extras is no longer a dependency. You can still install it of course, and I still use it, but speedwm does not depend on it anymore. Either way, that’s it for this post, just a little update on speedwm since it has been over 2 months since the last release of speedwm was released. Expect 2.0 to take a long time, as I do not feel like pushing another update adding minimal changes. Thank you for reading, check out speedwm if you want an easy way into dwm and like efficient software, and have a good day!

-
- - - diff --git a/articles/post46.php b/articles/post46.php deleted file mode 100644 index 9a70a88..0000000 --- a/articles/post46.php +++ /dev/null @@ -1,34 +0,0 @@ - - - - -libvirt is the worst program ever made.. - - - - - - -
-

libvirt is the worst program ever made..

-

2023-02-06

-

Another rant.

-

Warning: This blog post, unlike most of my others features strong language, because I hate libvirt. Please leave if you're sensitive to this.

-

I really, really REALLY hate libvirt. In fact it may be the worst program I have ever used, in fact it even manages to somehow outclass a lot of nonfree software, it is that bad. It's so bad I'm going to say fuck for the first time on this blog. And yes, I will take advantage of that. But first, what is libvirt and why am I complaining about it?

-

First, for this to make sense I'm going to talk a bit about my computing setup. I've got a fairly normal computer with an Intel Core i9 (backdoors included), and importantly two graphics cards (AMD RX 570+580), allowing me to pass one through to the virtual machine. As my host operating system, You guys know I use Gentoo, the best GNU/Linux distribution with a minimal kernel configuration and on top of that is speedwm with all the toggles set to zero. This Gentoo host is also LUKS encrypted. This is because the host is only used for running my virtual machines, which act as my actual "host". You can compare this to something like Qubes OS, where each operating system is its own container, only more based and more difficult to set up.

-

I do this because it allows me to easily monitor and backup each "machine". It's also pretty nice for security since I can just destroy the VM whenever I want, and I can choose to only pass through my mouse and keyboard and nothing else. Also, if I find a new cool GNU/Linux distribution I want to try, just clone the existing VM, rename it and install and when I'm done I can destroy that VM.

-

Now, to do this most people including myself use QEMU with KVM. QEMU is pretty nice and doesn't suck as much as libvirt does (we'll get into this shortly). QEMU doesn't do virtualization by itself, it's actually an emulator but combined with KVM (built into the Linux kernel) you've basically got a virtual machine. Only problem is that QEMU with KVM is very complicated and requires a fuck ton of different arguments to even work. So people write shell scripts to do this, which is fine, I'm all for scripting your way to the result you want but most people don't want to bother with this. So then, someone had enough with QEMU being difficult to use and writes a program called libvirt and it is the ungodly garbage responsible for all pain and suffering in the world. Seriously. libvirt basically has its own configuration file, which it then translates into QEMU argument on the fly and runs using your default shell. Fairly simple.. or that's what it should be if libvirt wasn't a garbage program written by absolute retards who have no business doing anything computer related.

-

Why does it suck so much?

-

Now that you hopefully understand what it is, why do I hate it so much? First of all, it creates more problems than it solves. What's the solution to having a complicated way to configure a program? Just add an even more complicated way to configure it, that will be perfect. QEMU is configured by using arguments like other programs, this gets complicated with a lot of arguments but it can be managed with a shell script. libvirt has an even longer configuration file, which is configured in HTML-like syntax that has been adapted to libvirt, so not only does it fail to solve a problem, it just forces the user to learn a new config and shove more shitty software up the already complicated and fucked up software stack on GNU/Linux.

-

How can libvirt suck more?

-

To make matters even worse, once the libvirt service has been started, it straight up refuses to fucking stop again. I run rc-service libvirtd stop and what does it do? Oh yeah that's right absolutely fucking nothing. Except it refuses to give me my USB and PCIe devices that was given to the guest so that means no ethernet anymore. That means I'm going to have to reboot my computer entirely and decrypt my hard drive before I can even try again. Fucking thief.

-

As if that wasn't enough, it doesn't even tell me when there's a configuration error. It just tries to start, silently fucks itself, steals my PCIe and USB devices, refuses to stop, forces me to reboot until I manage to find and fix the problem. You might be screaming right now, saying READ THE LOG FILE READ THE LOG FILE, but the log file contains nothing but shit, nothing useful, just obvious things like 'qemu started' or something along those lines.

-

That's where it ends right? Right? Well, no. Recently it has started failing to start for absolutely no reason other than just not wanting to start. It ends with me just rebooting over and over hoping it will FINALLY pass my mouse through and let me start using the virtual machine. Fuck libvirt.

-

End.

-

Well, that's the end of this one. I will probably go more into detail on how this setup works and why it is still superior to using an operating system on bare metal like most people do at some point. Have a good day!

-
- - - diff --git a/articles/post47.php b/articles/post47.php deleted file mode 100644 index 643cd20..0000000 --- a/articles/post47.php +++ /dev/null @@ -1,60 +0,0 @@ - - - - -Ethical software is not ethical and should be abolished. - - - - - - -
-

Ethical software is not ethical and should be abolished.

-

2023-02-07

-

Good afternoon good sirs! So I think most of you that follow my blog are free software and privacy supporters. Even if you support the 'open source' movement more than the highly based free software movement, I think we can both agree on the fact that ethical software is not ethical and might actually be less ethical than nonfree software. I want to talk about this because while it is nothing new, I got reminded of it and thought it was an excellent topic for today.

-

If you're out of the loop, or maybe haven't fallen for the free software ideology as much as the rest of us, what is "ethical" software and why should it be abolished? Ethical software is a software movement similar to the free software and open source movements, which strive for freedom in technology. However, the difference is ethical software ultimately is not about user freedom but rather a hate license that allows users of the many licenses to allow and disallow usage of the software and source code based on the political views of the individual using the software. Don't worry, it doesn't end there because the licenses aren't just about politics but also other world "issues" (depending on your views).

-

Let's take the NoHarm license for example. It is recommended by the ethical source website and is one of the many licenses they promote. Most of the license looks similar to the GPL, that is until you get to section 5 where we can see some radical differences. This is also where most of the stupid terms can be read. But first, let's read the preamble where it says "As software developers, we engineer the infrastucture of the 21st century" and "We envisage a world free from injustice, inequality and the reckless destruciton of lives and our planet". Now we can see their priorities, it's no longer about user freedom but instead about social justice and promoting political ideas. Free software is for everyone, absolutely everyone, even the people who don't support it. The 'Do No Harm' license however is for everyone, but only if you believe in the same ideas as the author of the software.

-

Let's read through the first section, 'abuses of human rights'.

- -

Most of this seems somewhat fair, as it's already illegal in most countries (hence abuses of human rights). But this is where the first problem comes in, why does a free software license need to mention any of this stuff when it's illegal anyway? And if it's illegal, chances are you don't care about following a software license anyway. Even if it's not illegal in your country, most of this is not even related to software or freedom. A license should not punish you for commiting any of these acts, that's why we have law enforcement. You might say, I don't do any of this so I don't care but that's just stupid. Aren't we fighting for user freedom? Why settle down just because you're following the license?

-

Next we have 'environmental destruction'.

- -

Here we can see the license devolve further into the insanity that is politics. Even though the average person is not going to commit most or even any of the acts mentioned here anyway, we're fighting for user freedom, aren't we? 'The extraction or sale of fossil fuels' is stupid, because it does not even do any harm to living creatures on Earth, but rather benefits humanity in one way or another. I feel like this has slowly devolved into an anti-capitalism kind of license, which is very different from what it says in the preamble. Then we have 'Industrial processes that generate waste products that threaten life'. Nuclear generates (potentially) deadly waste products, yet you depend on it.

-

Alright, next is 'conflict and war' which is more stupidity for various reasons I'll go into in a moment.

- -

Okay, why is this stupid? First of all, if you're alright with commiting WAR CRIMES, do you really care about following a software license? No, and for the average person, good luck even starting a war. If you somehow manage to start a war, and want to use the software, and still care about following the license, it's still really stupid, a software license should not to any normal human being decide whether or not you can use it for war. I think we all can agree on this, no matter your opinion on war.

-

'Weapons manufacturing' is stupid too. There are valid, legal uses of weapons, such as hunting. This means, if I want to hunt I cannot use any ethical software. Really, really stupid. And violence is up to law, so it is pointless to put in a software license. Despite all of this, so far it's been at least somewhat reasonable. All that changes now, as it mentions 'addictive or destructive products and services'.

- -

Now, what's wrong here? A lot, there are so many flaws here and I'll get into some of them. First off, it disallows gambling, which might be the first actual software related clause in this entire license. Yes, that's right. We're this far in and finally a real software license clause can be found. Anyways, this is stupid because there are a lot of ways to get around this, gambling is actually kind of subjective. I do think this is a bit too restrictive for a free software/open source license, and it would be considered nonfree due to section 5.

-

As for Tobacco, tobacco is definitely addictive, but it's up to each individual and no one is forcing you to use it so I think this point is unnecessary. This is also where the cracks in the license start to show, because how do you even integrate software or even electricity into tobacco? Anyways, for addictive behaviours, there are even more flaws with the license, because there are a lot of things that can be addictive. Does this mean you can't use the program with video games? What about using it at all, because the software might be addictive. Yeah, I don't know what they were thinking when they added this to the license.

-

The next section links to some other licenses, such as the 'Universal Declaration of Human Rights' and 'Convention on the Rights of the Child', none of which belongs in a free software license. I won't go into too much detail about this but you can read these licenses yourself if you want. The rest of the license continues like a standard copyleft license, which means all the cuck licensing tricks (such as relicensing) are not possible to pull off.

-

Now, finally, what do I think about 'Ethical' software? I think ethical software is unethical, more so than nonfree software. Despite some of the acts here being morally questionable, free software builds on fundemental ideas such as making sure every user of the software is guaranteed the four freedoms. This means, even if you're a war criminal who violates human rights, or something like that, you can still use and benefit from free software. You know, this is what I hate with people who constantly use social media, they are exactly the kind of people who would use and write a license like this. They care more about politics and social justice than writing a quality piece of software, or even making sure users are free to do whatever they want with the software. SJWs don't make the world a better place, they make it a significantly worse place, where freedom is ignored in favor of political opinions.

-

That's it for today, let me know what you think about ethical software, and have a good day!

-
- - - - diff --git a/articles/post48.php b/articles/post48.php deleted file mode 100644 index 9908688..0000000 --- a/articles/post48.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - -Software update - - - - - - -
-

Software update

-

2023-02-25

-

Today I want to just quickly talk about some important (and some lesser important) stuff regarding my software projects. First of all, let's talk about spmenu. In addition to the color support I added a month or two ago, spmenu now has image support. I initially couldn't think of many uses for this, however it's actually really useful. Let's say I want to list out all my wallpapers and set one as my wallpaper. My current wallpaper script actually uses a separate program for that, sxiv. But now that spmenu has image support I can actually just preview the wallpapers in spmenu right away, without an external program. This actually makes it more powerful than a lot of terminal emulators. Pretty cool if you ask me.

-

I have also made significant changes to another one of my projects, that being spDE. It now includes a helpful script which handles starting speedwm but more importantly handles installing configuration files. This means to install spDE now you only need to emerge it and use the spde commmand to set it up with configuration files. Saves even more time for me, and if you need an easy to use but efficient desktop environment which allows you to easily get into efficient software it's also good for that.

-

I also have a new project now called ivtools. ivtools is mostly a collection of ffmpeg and imagemagick snippets, whenever I need to do something with a video file I will put the ffmpeg command in a script. The goal is to eventually have scripts for most simple things a video editor can do, so that you don't need to start bloated editors like Blender or kdenlive when you just want to do basic video editing like adding music or cutting video. You can get ivtools here.

-

I have recently started using a program called dnote. dnote is a dmenu fork, but the only similarity it retains is libdrw and the general structure of dmenu because dnote is a notification daemon. This similarity to dmenu makes it really easy to add new things into it. I have myself added .Xresources and alpha into dnote. You can get my build here if you want to try it out. You'll definitely see me using this in shell scripts soon, in fact I plan on migrating speedwm modules and speedwm-extras scripts to using it. It's great, pretty much notifications but better in every way.

-

As for speedwm, I'm pretty happy with it and while I have plans on doing things with it, they'll probably be in the form of a new project. For one, I want a rule and keybind configuration file which will require major changes to be made. I also want to rewrite the status, so that each status module is a different bar module.

-

Anyways, that was just an update on the projects I've been working on. No need to drag this blog post out longer so thank you for reading, have a good day!

- -
- - - - diff --git a/articles/post49.php b/articles/post49.php deleted file mode 100644 index 4722f1c..0000000 --- a/articles/post49.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - -spDE - Now also on Arch based distros - - - - - - -
-

spDE - Now also on Arch based distros

-

2023-02-27

-

Yesterday I decided to get some work done and ported most of my Gentoo packages for my software, such as speedwm and spmenu but much more to Arch. Of course, first I had to learn how to actually do this, but as it turns out, it’s actually even easier than on Gentoo. I was able to create all of these packages, including testing in less than an hour.

-

I had to make a few minor changes to spDE for it to work on Arch, such as changing the owner of the home folder to the user rather than the user’s group but for the most part it works perfectly. No, the package will not be on the AUR as I do not want the user to have to deal with compiling the stuff locally. I also don’t want to deal with the AUR moderators potentially deleting packages.

-

With that said, if you want to install spDE on your Arch box, add my arch repository (instructions in README) and pacman -Syyu. Then simply pacman -S spde provided the sync completed successfully! The rest of the steps are the same as on Gentoo, run spde -i, spde -a <your user> and finally startx /usr/bin/spde -r to start spDE.

-

spDE on Arch is nearly identical to spDE on Gentoo. There are a few minor differences but they shouldn’t be that noticeable. If you don’t want the entire spDE package, you can choose to install the stuff individually, too. There are packages like speedwm, speedwm-spde, spmenu, libspeedwm, speedwm-extras, fontctrl and so on which can be installed without installing the entire thing.

-

That was just an update for those of you that are interested in running spDE on Arch, I have been putting this off for a long time so I’m glad I finally did it. Thank you for reading, install spDE if you want, and have a good day!

- -
- - - - diff --git a/articles/post50.php b/articles/post50.php deleted file mode 100644 index 4418b9a..0000000 --- a/articles/post50.php +++ /dev/null @@ -1,32 +0,0 @@ - - - - -Normies are destroying GNU/Linux - - - - - - -
-

Normies are destroying GNU/Linux

-

2023-03-09

-

So, because this blog post marks blog post number 50, and because the first blog post is 1 year old today, I thought to celebrate I'd do a rewrite of my first blog post, which still holds true, actually more so than when I intially wrote it. Granted, the original blog post is terrible, it was fueled out of frustration and nothing more so let's give the topic the chance it deserves.

-

As well all know, GNU/Linux is an operating system and it has always been the outcast, it has always been less popular than other operating systems like Windows and macOS. Out of the outcast operating systems like BSD, Haiku and more however, it's pretty popular and it's growing in popularity. While this may seem like a good thing at first, when you actually dig deeper into what that means for GNU/Linux, you'll find many problems and I want to talk about those today.

-

So let's go back into the early days. Linus Torvalds developed the Linux kernel, which was used in combination with the GNU project. This means we now have a completely free software operating system. Great, now we don't have to use spyware nonfree software that doesn't respect your freedom anymore and everything is good for the small userbase. Previously GNU/Linux followed the UNIX philosophy rather closely, which is what made it so great. Of course there were exceptions to this rule, such as X11 (and today Wayland), however most software was minimal, and closely followed the UNIX philosophy like it was a religion, as that was expected out of software.

-

As GNU/Linux got more mainstream and normies got their hands on it, this freedom, this minimalism, all this stuff that made GNU/Linux so great started to disappear. When normies found this free operating system, naturally being normies they didn't want to actually learn anything about minimalism and free software, and certainly didn't want to enjoy any of the perks of it. Instead of that, they initially whined and complained about how it was different from what they're used to. And we, members of the GNU/Linux community in response did everything in our power to make the "Year of the GNU/Linux desktop" happen. Except..

-

We didn't. In response to normies complaining, we as a community at large started developing garbage, bloated software that throws everything that makes GNU/Linux and UNIX in general so great in the trash. We're no longer using text streams, we're no longer writing quality software with quality code, instead we're focusing on developing libraries on top of libraries that just add bloat to a project and create huge basically packages of software in an effort to please normies who refuse to appreciate the beauty of UNIX-like operating systems and just wanted to stick to what they're familiar with.

-

Here's the thing, If you're this kind of person who doesn't want to learn GNU/Linux, you don't want to learn about UNIX-like operating systems and you don't want to spend any time out of your day learning this stuff then why even bother using a new operating system in the first place? At that point, you might as well stick with Windows or macOS. But alright, fine. We can still have our section of the GNU/Linux community where traditional UNIX/Minimalist views are still appreciated, right? Well, no because eventually programmers start writing software which of course depends on all this normie software which is absolutely awful and now it becomes almost impossible to have a functioning system on GNU/Linux without this garbage software.

-

I haven't given any examples yet, but in my first version of this blog post I referred to Snaps, AppImages and Flatpaks, and while those do still meet the criteria here (although not in the present), I want to give some more examples which might make more sense. First, systemd. systemd is a collection of tools for GNU/Linux, and although many people hate systemd because it is "an init system", it is really a suite of tools. Therefore calling it bloated is not justified. However what is justified is valid criticism towards it. systemd provides a tool named "logind". So many programs depend on this, it is pretty much impossible to have a modern GNU/Linux system without this program installed on your computer. Now, that should be taken with a grain of salt because there are many different implementations of this tool, and those of you that use Gentoo may be familiar with one implementation called elogind. Still, I think this is an excellent example of dependencies that are used so much you cannot escape them.

-

But there are so many programs like these that we can't really escape, and the cause of these programs existing is usually the same. Normies want "easy" software, so in response we write terrible software which a normie will think is easy because Windows is terrible. However the worst of it came around the time Linus Tech Tips and all these other well known technology "entertainment" channels started covering GNU/Linux and giving it attention. When that happened and Windows/Mac users gave this OS a proper chance, developers around here scrambled to write as much normieware as possible to please these new users in the hopes of converting them into GNU/Linux users. Of course this failed, and just resulted in more terrible software.

-

I call this the "gaming wave", because suddenly all these gamers (often with NVIDIA graphics cards) came over here, because that's what Linus Tech Tips' fanbase is and wanted to play games. Of course, this failed because despite the effort from the people who play games around here, most GNU/Linux users don't really play games. In fact I barely play games myself anymore. I have nothing against people who play games, but the people who play games on GNU/Linux certainly have some blame to take here.

-

Lastly, before I end off this blog post I want to mention a few things regarding Wayland. In short, I'm definitely against it and that's for a few reasons. Wayland brings a lot of good things to the table, such as a cleaner codebase, less screen tearing, perhaps HDR support in the future, and so on and all that is fine by me. No complains there. Where the problem starts to show however is from a developer perspective. Yes, the Wayland display protocol is more minimal than X11 (that's not really an achievement) but a lot of that is because the Wayland mess has been moved over to the compositor forcing any developers to write thousands of lines of just absolute junk. This is absolutely terrible, and until the developers of Wayland change direction (highly doubt they will), I'm sticking with X11 until it's no longer feasible to do so.

-

Either way, that's what I wanted to say, stop using all of this stupid software whenever possible, and become a based GNU/Linux minimalist. I plan on getting a page up on replacements for stupid software which will kind of act as a guide on how to get into GNU/Linux minimalism for those of you that fell for this stupid software. If you have any questions or thoughts, feel free to send me an email.. and have a good rest of your day.

-
- - - - diff --git a/articles/post51.php b/articles/post51.php deleted file mode 100644 index 65e06fa..0000000 --- a/articles/post51.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - -Important site update (and the Matrix) - - - - - - -
-

Important site update (and the Matrix)

-

2023-03-15

-

I'm going to keep this one short and to the point. As some of you may know, my domain is going to expire. It is going to expire on the 31st of March 2023, which is not far from today and that's what I'm going to talk about.

-

For those of you that don't know, my website uses a "free" TLD (top level domain). This seemed like a good option last year, but as I want to continue this stuff, it presents a problem. Freenom is the company that provides the .gq TLD, along with a few more domains such as .tk. Freenom has shown themselves to be problematic, and they have done things like taking away domains from people after the websites have become too popular. Renewing their domains is also difficult and annoying, and even then doesn't work all the time for all people.

-

Because of this, I decided to write this blog post, and to make sure my readers have a place to keep up with me if my website does collapse, I've created a Matrix channel which I recommend you join. You can join it here. You can start with Element, it's all free software unlike the previous Discord server.

-

I don't plan on making this a big thing like Forwarder Factory was, and in fact I don't want that either. This is simply going to be a small place for me to talk to my readers, discuss the website and other things like that.

-

Either way, my domain expires March 31st if I'm unable to renew it. If I manage to renew it, you can continue using the site like normal for an additional year. Otherwise, I'm simply going to purchase a new domain. I do not yet have another domain, which is why I recommend you join the Matrix channel.

-

That's really all I wanted to say, as the writer here I think it is important that you are informed about everything. My website code is all available for free on Codeberg so you can still have that if you want. Thanks for reading, have a good day!

-
- - - - diff --git a/articles/post52.php b/articles/post52.php deleted file mode 100644 index e6ded04..0000000 --- a/articles/post52.php +++ /dev/null @@ -1,26 +0,0 @@ - - - - -Friendship ended with Gentoo, now Arch is my best friend! - - - - - - -
-

Friendship ended with Gentoo, now Arch is my best friend!

-

2023-03-26

-

Alright so I have a brief announcement or something today and that is, I have officially stopped using Gentoo. Yes that's right, the Gentoo elitist is now an Arch cuck. But why, why would you commit such a crime you might say? Well, Gentoo has actually been giving me more and more problems for months now, and it doesn't seem to get any better.

-

I've had so many dumb issues with Gentoo recently, such as Xft fonts being broken, packages failing to emerge, --depclean removing my entire system, and the final straw, gnome-keyring issues that just do not occur on other GNU/Linux distributions. In case you're not aware, I have been using Arch on my laptop for months now, and while Arch has some annoying issues such as GPG keys constantly breaking pacman when updating, I find that it works much better now.

-

To make matters worse for Gentoo, syncing the repositories takes a very long time, and it's valuable time that I do not want to spend just because a program is slow and written in Python. Moving over to Arch was not difficult though. I said 'fuck it' yesterday at around 04:00 in the morning, and started installing Arch over Gentoo. Thankfully, as you guys know I have an arch repository containing nearly the same programs as my gentoo repository (overlay), and as such I was able to install my config files and all my programs using one command. It's super nice, otherwise I would've probably spent much more time on this.

-

Anyways, as for my overlay, I will probably update it every once in a while using maybe a docker container, but I'm going to be focusing on the arch repository because it's what I'm using. For those of you that actually use Arch, this might be good news for you because it means you will always be able to install my software using pacman. I know that some of you will probably be disappointed about this, because I'm kind of known as a Gentoo user at this point, but I just can't take Portage's stupidity anymore. If you need to however, feel free to remove my feed!

-

I also took the time to move /home to a separate partition, which is really nice if you want to reinstall quickly. Whatever, that's all I needed to say with this blog post. Have a good day!

-
- - - - diff --git a/articles/post53.php b/articles/post53.php deleted file mode 100644 index e2049b9..0000000 --- a/articles/post53.php +++ /dev/null @@ -1,39 +0,0 @@ - - - - -I switched back to Microsoft Windows.. here's why! - - - - - - -
-

I switched back to Microsoft Windows.. here's why!

-

2023-04-01

-

As you guys may know if you have been a speedie.site reader for a while, I was a Gentoo user, and recently I switched to using Arch full time. However, I am yet again switching operating system because I just found out Windows is the best operating system ever made.

-

Linux sucks, but Windows is awesome!

-

Now, most of you probably use some open source Linux distribution on your computer. But Linux is open source, and that's bad. That means Russian hackers can steal your porn collection because of course they can see all the source code and backdoor it. When you're using Microsoft Windows on the other hand, the only one who can access your data is Microsoft, who will send that data to the NSA. This also makes sure your data is safe, and that you're following the law like any good citizen. When I'm using Windows I feel safe and no malware has access to my data. The same cannot be said for Linux or any other open source operating system

-

These Linux users who never go outside or shower will say that this is malicious, or that it is spyware, or any other nonsense but the fact of the matter is the government already knows everything about you anyway. You should not care about privacy if you have nothing to hide, so of course Linux users have a lot to hide. The government would never do anything bad anyway, they only want the best for you.

-

Tiling window managers suck

-

Why would you use a tiling window manager? Only hackers use those. Tiling window managers are also really hard to use, I mean think about all the keybinds you need to remember to get good at using one.

-

What about speedwm? I'm just kidding, I've been secretly using GNOME for years, and I was never using speedwm in the first place. Hating Wayland? Actually, I've been using a Wayland session on GNOME for a long time now. As we all know, X11 is old and slow, and it's not written in Rust so that makes it instantly bad. spmenu? It's just rofi with a theme.

- -

C programming language? Hell no, it's so hard to learn and it's so old. Real programmers use JavaScript for the frontend and Rust for the backend. Recently though, I've started using C# which is superior to both of these in every way. We all love Micorsoft.

-

Vim is only used by furries, neckbeards and weirdos

-

Vim is a meme Linux users force onto new users. In reality, Vim is hard to use and it's so slow, I can't even figure out how to exit it. If I can't even exit it, how can I use it to write code? Why wouldn't you just use a mouse anyway? It's not 1983 anymore, we have modern, proper computers for real people now. The only people who still use Vim are neckbeards who want to look cool on the internet but in reality don't have a life.

-

Visual Studio Code on the other hand is the greatest code editor ever and it's what I've been using for months now, while people were under the impression that I'm an avid Vim user. It's "open source" so that the Linux neckbeards will use it, but uses a mouse, because it's 2023 and if you're not using a mouse for everything except typing, you're lost in the past. It also supports JavaScript plugins and has a lot of Microsoft telemetry, so they know you're doing a good job writing programs for the future.

- -

Installing programs

-

Linux users claim that using their terrible package managers is better than downloading executables from the internet directly. This is just not true, because the package managers can be hijacked remotely by Russia to spread propaganda to all of the users. This doesn't happen when you download random executables from the internet, because Microsoft Defender is guarding your computer, and has a 100% success rate. As soon as malware tries to attack your computer, Microsoft Defender is there to stop it.

-

Software minimalism

-

Software minimalism is all a big joke. Why do you need your computer to use 100MB of system RAM idle? Unused RAM is wasted RAM. Microsoft makes sure to leave no RAM wasted, which makes it much better. Unlike suckless, Microsoft makes feature complete software that normal people can use. In fact, suckless is just a software project created by Microsoft's worst employees created to trick Linux users into thinking Linux is unusable, thus getting them to move over to Windows. Microsoft makes sure people join the beautiful land of Windows, where no one falls for memes, and everyone is secure.

-

Conclusion then. After I found out Windows is better than Linux, I have decided to stop working on my meme projects, and join Bill Gates in helping him build the best operating system for normal people. Linux furries and neckbeards, join the land of Microsoft today, stop using the Matrix meme, come back to Discord, assist Microsoft and the NSA in catching criminals, and become a real member of society today. It's only a $100 operating system.

-
- - - - diff --git a/articles/post54.php b/articles/post54.php deleted file mode 100644 index b7deead..0000000 --- a/articles/post54.php +++ /dev/null @@ -1,24 +0,0 @@ - - - - -News/important update regarding the site - - - - - - -
-

News/important update regarding the site

-

2023-04-14

-

I will keep this one short so you can actually read through it. Yesterday (13/04/2023) I purchased a domain, because as we all know I do not trust Freenom to keep my site up. This domain is a lot more reliable, however it does mean you will have to swap out '.gq' for '.site'. I have redirected some parts of my site. I have redirected the main speedie.gq domain, and I have also redirected rss.xml so that RSS readers won't complain. You should still change the URL, however if you exclusively consume my website through RSS you will get the message anyway because of this. Finally I redirected the wiki.

-

Switching over is not hard. The page is identical, and although SSL was not functioning earlier today, I have resolved the issue. So to switch over, just replace 'speedie.gq' with 'speedie.site'. This is especially important if you use Arch and my repository. If you do, you must edit /etc/pacman.conf and replace the URL. There may be a few sharp edges as of now, as I simply ran a few sed commands on the old site without looking through it properly, if there are issues please email me so it gets fixed. I should also add I moved from Nginx to Apache a few days ago, so the speedie.site wiki and the speedwm wiki should be functional again.

-

Anyway, that was just a short blog post about something relatively important. I will probably keep the speedie.gq domain updated as well, but I cannot guarantee it will work properly. If you have any questions, feel free to email me, or simply join the Matrix space. Either way, that's it, have a good rest of your day!

-
- - - - diff --git a/articles/post55.php b/articles/post55.php deleted file mode 100644 index 84b3edc..0000000 --- a/articles/post55.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - -Dear bloggers: Your RSS feeds suck. - - - - - - -
-

Dear bloggers: Your RSS feeds suck.

-

2023-04-19

-

Now that most of my issues regarding this site are resolved, I want to start writing about something. I have a lot of topics I want to talk about, however for many of these topics there's just not much content to them, so I apologize for the length of some of these.

-

Anyways what better topic to start with than this one. My blog isn't perfect, I post a lot of garbage here quite often, but what pisses me off is when people will write blog posts, have an RSS feed and then ruin it with one thing. They will put about 1/10 of the blog post in the description tag, and then they will have the blog post in full on their website.

- -

This is extremely annoying, because it means I have to open up my bloated web browser just to view your blog post which could normally be read using my RSS reader, which is designed for reading blog posts. What if I want to read your blog post on the command line? Or what if I want to read your blog post when I don't have internet?

-

Good RSS readers like Newsboat and sfeed store the full feed locally, meaning you can actually read the articles even when you don't have any internet connection. But when you force me to go to your website, I can't just save it when I do have internet and read the blog post whenever I want to read it.

-

Now, I know why you would do this. If you have a site, chances are you want people to visit it. RSS is convenient, very convenient and I'm going to admit I don't actually visit the sites for blogs I follow very often, usually I read the feeds every day and then very occasionally visit the websites. But I still think this is annoying.

-

So, if you're going to have a blog and you plan on using RSS, please provide the full blog post in the description tag. I know this can cause issues with paragraphs, but you can steal my feed as a base if you want. Thanks for reading, and have a good day.

-
- - - - diff --git a/articles/post56.php b/articles/post56.php deleted file mode 100644 index 824dffe..0000000 --- a/articles/post56.php +++ /dev/null @@ -1,49 +0,0 @@ - - - - -Why I don't use Wayland (and how it can be improved) - - - - - - -
-

Why I don't use Wayland (and how it can be improved)

-

2023-04-28

-

Today I want to talk about Wayland, and why I don't use it. In case you're a normie and don't know what Wayland is, Wayland is this new display protocol created by the people over at Freedesktop. They want it to be better than the display protocol most GNU/Linux users are already using called X11. While I'm not against the idea of a new display protocol, in my opinion Wayland is a failure, and it fails at doing everything X11 did right, and that's what I want to talk about here. Note that most of this will be from a developer's perspective; if you're using GNOME, KDE or maybe even one of the many wlroots based compositors, your experience on Wayland is probably going to be pretty good.

-

Terminology

-

First, let's talk terminology. On X11 we have something called a 'Window manager', and as the name implies it manages your window. The window manager is the root window, meaning it's the first window. Other than that, it's just like any other window you may have. This is quite powerful, because it means in theory anything can be a window manager. You can try this for yourself on Xorg and xinit by running startx /usr/bin/firefox. What you should have is an X11 session with only firefox open and nothing else. This is why we have window managers, they allow us to spawn more windows and place those windows whereever we want. Even desktop environment users have a window manager, because your desktop environment comes bundled with one.

-

On Wayland and X11, we have something called a compositor. Let's ignore Wayland's definition completely for now. On a basic level, the compositor provides fancy effects such as transparency, rounded corners with anti-aliasing, shadows, animations and other things you may or may not want. One of the most popular compositors today is called Picom, and most standalone window manager users use it, if they use a compositor at all. This works by creating buffer where these effects are added, and then displaying the buffer to the user. This is why older machines may feel slow when a compositor is running, it's just not displaying that buffer quickly enough.

-

In X11, a client is pretty much the same thing as a window. I am going to be using the term 'window' throughout this blog post, but client is what I usually use when referring to an X11 window.

-

'Xorg' is an implementation of the X11 protocol, and it's the implementation most users are using. There are other ones like XFree86, but most users use Xorg.

-

The compositor problem

-

This is where Wayland's problem for me comes in. On X11 these two components are separate, so I can pick and choose each component and just combine what I like. With Wayland, they have decided to combine the compositor and window manager into one program, which to make it even more confusing is also called a compositor. Now, why is this so bad?

- -

Those are the problems that come as a result of combining the compositor and window manager. While I'm sure there could be benefits to combining the compositor and window manager as well, I just cannot think of a single reason.

-

What change do I want to see?

-

I want a more minimal display protocol. Wayland is more minimal so I think it passes here. What I also want is a more modular display protocol, and this is where Wayland seems to fail. X11 did this right, but I want it even more modular than X11. Everything should be separate, as long as it doesn't harm the user experience. Not to mention, more modular software is usually more secure, because each module is much smaller and easier to maintain.

-

I also want a library which allows creating BOTH X11 and Wayland clients without writing any extra code for it. This would be ideal, although I'm sure there are potential challenges from doing it this way. You might say, "Just use GTK or QT" but they also require writing extra code for Wayland or X11 support. This leads to developers not supporting one or the other.

-

For example, I want to add Wayland support into spmenu. I'd be happy to do so, but the problem is it would require rewriting the code for creating the window, handling events, keybinds, clicks, drawing, mapping, and more. It's just not something I want to deal with, which is why I've chosen to not write any of my software to use Wayland native libraries. There is XWayland, but to my knowledge there's no such thing in reverse.

-

Conclusion

-

I want to mention that I'm very much open-minded towards a new display protocol. I'm all for a new, more minimal, more stable display protocol. It's just that Wayland makes it a pain to write compositors, and in many ways it's a downgrade from X11, which is really old I might add. That's not to say Wayland has no improvements and X11 is perfect. The most popular X11 implementation, Xorg is extremely bloated and has a lot of legacy code that really doesn't matter today and the protocol itself is probably not much better.

-

It also has absolutely horrible security. But all things considered, I think X11 just has much better ideas on what the desktop should be than Wayland does. If Wayland improves the things I don't particularly like, I may end up switching to it. But as of now, X11 works fine for me and the benefits of Wayland just aren't worth it, so I am going to be sticking with X11. If you know of any solution to this problem, I'd love to hear it, and I'd love to give Wayland a proper chance.

-

Thank you for reading, have a good day!

-
- - - - diff --git a/articles/post57.php b/articles/post57.php deleted file mode 100644 index db48c74..0000000 --- a/articles/post57.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - -Ungoogled Chromium: The best browser for most people - - - - - - -
-

Ungoogled Chromium: The best browser for most people

-

2023-05-01

-

Today I want to talk about my favorite web browser which I have been using for several months now and that is Chromium, specifically Ungoogled Chromium. Ungoogled Chromium is the best browser because it's fast, it respects your privacy, but also doesn't provide any extra bloat or anything, it's just a fast, privacy respecting web browser that does everything you need and nothing more. In a lot of ways it's the best web browser for minimalists, but also for normies because it requires no learning coming from Chrome or whatever.

-

If you are on Arch, you can get it from the AUR, and I also have a package available in my arch repository, so if you're using speedie-aur you can just pacman -S ungoogled-chromium. When you start it for the first time, if you're coming from regular Chromium or maybe the horrible spyware that is Google Chrome, you're going to notice that it looks a bit more minimal. That's because most of the Google junk has been removed, so what you have is what you actually need out of a web browser. By default, no search engine is active/enabled though, but if you want one you can go to the settings like in regular Chromium and simply add one.

-

The second thing you're likely going to notice pretty quickly about Ungoogled Chromium is by default it actually doesn't save cookies, so after you close your web browser you have to log in again. Now, I consider this a feature rather than a bug for security reasons, and while this isn't a security oriented web browser, most of its users are privacy enthusiasts, so I consider this a nice default. If you don't like this though, you can just change it in the settings. If you're setting up this browser for a normie, you may want to enable saving cookies, because in the society we live in normies would be very confused when their web browser doesn't keep them logged in.

-

Ungoogled Chromium is not hardened by default though. For good security I would install JShelter, uBlock Origin, LocalCDN, and a few other privacy oriented extensions. I would probably also install Vimium, which allows you to follow links using f and use general Vim-like keys to navigate the web, and of course a dark theme of some kind. But how do we install extensions anyway?

-

The reason I find this browser is better than others is because it's based on the Chromium web engine making it extremely fast, but it also respects your privacy by removing all the Google junk. Chromium is a good browser outside of all that Google spyware, because Google knows what a good browser is. A good browser is fast, minimal and allows you to view websites and nothing more. Google has known this since the beginning, and that's why this is such a good web browser. Other web browsers often fail at this.

-

I should note that due to all the Google junk being removed, you can't actually install extensions through the Chrome Web Store. However there's an extension you can install manually, which will allow extensions to be installed from the web store anyway, but you should RTFM for that. The extension is available here, and was designed with ungoogled-chromium in mind. While you don't need it, it makes the process of "manually" installing extensions a whole lot easier. It even does updating for you, although it requires some user input.

-

As if this web browser wasn't already excellent, The --app argument makes it even more useful. In fact it makes all Electron applications basically obsolete. If you do.. for example chromium --app="https://speedie.site" you'll pretty much have an app for my website as the name implies just like Electron would do, except it's using your existing web browser. This makes it slightly more appealing. It even changes the icon to the favicon for the site. I'm using this feature for Element (the Matrix client I use) and Discord. I combine this with my run launcher to have super awesome web apps.

-

Overall, I highly recommend this browser. While it's not the most secure (you'd probably want GNU IceCat or LibreWolf for that), it's super fast, it's free as in freedom and it's minimal and clean. It provides sane defaults such as not storing cookies by default. It's a good web browser for both normies and people who know how to use technology, because I think both groups of people find its features appealing. If not, I guess the normie can continue using Chromium and you can use Ungoogled Chromium and get privacy from it. Thank you for reading, I highly recommend Ungoogled Chromium, and have a good day!

-
- - - - diff --git a/articles/post58.php b/articles/post58.php deleted file mode 100644 index 65348ec..0000000 --- a/articles/post58.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - -Swedish man rants about licenses again - - - - - - -
-

Swedish man rants about licenses again

-

2023-05-23

-

It is no secret that I strongly believe in copyleft licenses like the GNU General Public License (often shortened to GNU GPL or GPL) and the Mozilla Public License (MPL). Copyleft licenses as the name implies are the opposite of copyright licenses. With copyleft licenses, the user has the freedom to modify, study and distribute the software and source code. But unfortunately in recent years copyleft licenses have fallen out of favor thanks to tech companies like Microsoft heavily pushing too permissive licenses to developers. These licenses (which I will call 'cuck licenses' from now on) rob developers of their work. Now, it should probably be noted that I am not a lawyer, nor am I more experienced in any legal system that most people. I'm just here to talk about the best software license today.

-

With cuck licenses, the developer writes the code and puts it out on the internet like usual. The difference is there is nothing that prevents anyone from forking it and changing the license. You might ask why this matters. It matters because big tech companies like Microsoft, Google, Apple, Nvidia, Meta, and many more will take these free software projects, change the license to a nonfree license and no longer distribute the source code for the software. Most of these cuck licenses only require that the license notice is kept in every piece of code. However you're only distributing a binary though, the license isn't noticeable anyway.

-

I'm sure you can tell by now, but tech companies LOVE cuck licensers, because cuck licensers do the work for them and for free. The companies then just steal that source code and make their own proprietary variant. No attribution, no money, nothing. Some developer writes the code for free and a big tech company will steal it and make a nonfree spyware variant of it. When tech companies write software, they will usually license their own software too under the BSD licenses or more commonly, the MIT license. The MIT license is probably one of the worst licenses out there in terms of stripping the developer of his/her freedom. The user still has the freedom to use, study and modify the software. That is, until a tech company forks the project and changes the license to a nonfree one.

-

An example of a bad case of cuck licensing is MINIX, a portable UNIX like operating system. Because this project is cuck licensed, Intel decided to fork the project, apply some spyware modifications to it and relicense it under a proprietary license so no one knows what the code really does. Now all Intel users have this backdoor in their computer in what's called the Intel Management Engine (ME). Or take Google Chrome. Google forked the Webkit engine and made their own web engine called Blink. The Chromium browser which implements this engine is free software, but Google Chrome (which is very similar) is a nonfree program which does god knows what.

-

But you, the developer can fight back against this by licensing your software under a copyleft license. Copyleft licenses usually require that the forked software is licensed under the same license. So if you license your software under the GNU General Public License version 3, all copies of the software including forks are going to be licensed under that same license. This is great for developers because their code is always used for free software and not nonfree software. It's also great for users, as it means there will be less nonfree software to use and more free software to use instead.

-

I should note that I switched all software I've written from scratch to the GNU General Public License version 3 about a year ago or so from the MIT license and it gives me more freedom, and it also means everyone who uses my software or forks of my software is guaranteed freedom. It's a win for everybody, and it means together we're working towards a more free computing experience for everyone. It has its flaws though, which is why some may consider the LGPL or Lesser General Public License. This license unlike the regular GPL allows embedding the software in proprietary programs. This may actually be preferable in some cases, but in general you should stick to the regular GPL. I know there are more licenses than the GPL and MPL, but I'm not going to get into license specifics too much here. I'm mainly talking about the GPL because that's what I license all my software under.

-

Conclusion then. Cuck licensers write the software for big tech companies for free. They get nothing in return and users get a piece of crap proprietary program when the big company forks the originally free software program. With copyleft licenses on the other hand, the user is guaranteed the freedom to modify, study and distribute the source code or program. Switch to the GNU GPL today or any of the other GPL compatible copyleft licenses and truly become a free software computer programmer.

-
- - - - diff --git a/articles/post59.php b/articles/post59.php deleted file mode 100644 index c2f2e10..0000000 --- a/articles/post59.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - -Yet another update post. - - - - - - -
-

Yet another update post.

-

2023-06-03

-

Wow, look at that. Even more junk to fill my catalog and make it look like I've done more writing than I actually have. Oh well. I'll get straight to the point. At approximately 02:32 I quickly made the decision to move from cgit to Gitea for hosting my Git repositories and projects. For this reason, links to the old Git repositories need to be changed. This mainly applies to those of you that are using speedie-aur, or speedie-overlay. I'm assuming that's quite few of you, but just in case I'm putting this out there.

-

If you're using speedie-aur, you'll need to edit /etc/pacman.conf and change the Server to Server = https://git.speedie.site/speedie/speedie-aur/raw/branch/master/$arch If you're using speedie-overlay you'll want to remove the overlay and add it again. See the repository for more information. The Arch wiki article has been updated to reflect these changes as well, and so has the overlay.xml.

-

I have also moved over a lot of GitHub repositories to my Gitea instance, such as my Gentoo kernel for my ThinkPad and desktop, multiple OpenCore configurations, and more, but all Codeberg and GitHub repositories are still accessible. It should be noted though, that I plan on moving all website development to the Gitea instance rather than Codeberg.

-

What you may be screaming right now is WHY? I'll tell you why. Cgit is an excellent Git viewer, but that's all it is. A git viewer. It doesn't handle your repositories, no issue tracking, no pull requests, no users, nothing. This is fine when you're the only one working on a project, as you're going to do most work locally on your computer anyway, and then push using Git from the command line.

-

The problem is when you want to have any kind of collaboration, which is something I realized today (and yesterday). As some of my projects are becoming increasingly complex, I need a way for people to submit bug reports and fix issues. Emailing isn't convenient for the user, and it isn't convenient for me either. Now that I'm using Gitea, any user may create an account and simply create an issue or pull request. There's not any more to it, just simple. If you're familiar with GitHub or even one of the public Gitea instances like Codeberg, this is likely nothing new to you.

-

Now, while I'm writing this blog post I also want to talk about some future changes. I want to slowly move from w2wiki to simply a static website that people can edit through issues and pull requests. In my opinion this is a lot better, not only for security but convenience and flexibility. W2wiki is pretty good, but it is definitely not designed with security in mind, and it isn't hard for anyone to simply remove the entire thing with minimal effort, as happened to the speedie.site wiki a while ago.

-

While it is a static site for the most part, I may still be using PHP if necessary, especially for maintainence. No JavaScript however, although it should be noted that the Gitea instance does use JavaScript. There is just no way around it as far as I know, so it will have to do. All the JavaScript is free as in freedom, which is the important part. I have no plans to put JavaScript anywhere else on my site though, as long as it's feasible.

-

Anyways that's just a small site update. Have been busy with my spmenu Wayland port and other things like that, but now that it's complete I plan on posting more blog posts, as I have a lot of things I want to cover eventually. That's it for me, have a good day!

-
- - - - diff --git a/articles/post60.php b/articles/post60.php deleted file mode 100644 index 56c83e5..0000000 --- a/articles/post60.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - -You don't need to justify your decisions. - - - - - - -
-

You don't need to justify your decisions.

-

2023-06-08

-

I often hear people following my blog or just know me for one reason or another, and usually it goes something like this:

-
-

Hello speedie I enjoy reading your blog.

-
-

Thanks!

-
-

I’m using X nonfree software or Y desktop environment, sorry about that.

-
-

This is the problem. I see far too many people apologize for their choices in technology, but I want to make one thing clear. I am not here to judge your technology choices. If you want to read my blog on Windows and/or Mac, use nonfree programs, hate my software or ideas, or do something else I’m not personally a fan of then you are 100% free to do so. You don’t need to justify your use of software or hardware, that is a personal decision you are making. I am not going to make that for you, and while I may not agree with your decision, it is not mine to make.

-

I may suggest replacements for the software you’re - using if I believe it’s something you would benefit from (such as learning Vim or getting into tiling window managers), but I’m never going to force you to use/do something, or shame you for using the nonfree software or software I simply don’t like. I am also never going to force you to believe the same thing as me, that’s idiotic, and the definition of an echo chamber, something I’m very against. I don’t want 15 speedie clones, you should have your own ideas, and I should have my own ideas. If we agree then we do, if we don’t, then we don’t. I make decisions you may find stupid, you make decisions I may find stupid, and if we don’t debate each other’s ideas, we lose the ability to think for ourselves.

-

That’s not to say it’s harmful to criticize the choices others make, but you need to be willing to see both sides of the coin, and like it or not you need to accept the choice the other person is making, whether you approve of it or not. That’s just a short blog post for today, as I see this far too often, and I think it’s important to say this. I’m probably going to talk about Wayland development, Wayland libraries, Wayland protocols and Wayland implementations next time now that I’ve truly given Wayland development a fighting chance to win me over. That’s it for me, have a good day!

-
- - - - diff --git a/articles/post61.php b/articles/post61.php deleted file mode 100644 index c9de848..0000000 --- a/articles/post61.php +++ /dev/null @@ -1,35 +0,0 @@ - - - - -The Wayland experience - - - - - - -
-

The Wayland experience

-

2023-06-17

-

Today I want to talk about my experience using Wayland compositors and software, as well as developing Wayland clients for Wayland using the wayland-client library. I've talked about the protocol itself in the past, usually in a negative light because that's how I see it for the most part, but after using Wayland for a bit I have some more things to say about it, and I want to talk about those today.

-

First of all, Wayland is not a display server, just like X11 isn't a display server. X11 and Wayland are both display protocols, which then have to be implemented. X11 has a standard implementation, called Xorg. While this isn't the only implementation of the X11 protocol, it is by far the most used one. This is called a display server. Wayland on the other hand does not have a single implementation more popular than others, because each compositor has to implement the Wayland protocol themselves. This can lead to issues if a compositor doesn't implement a core part of the protocol. This means the compositor is also the display server. But because implementing an entire display server and following the Wayland spec is complicated and time consuming, libraries such as wlroots and swl have been created, which implement a lot of the Wayland functionality for you. This is really as far as standards go with Wayland, because every Wlroots based compositor is compatible with each other. The problem now is everyone is going to base on Wlroots, and for good reason because no one really wants to write all that code.

-

Except not everyone wants to use Wlroots. For example GNOME and KDE both have their own Wayland implementation (because of course they do), and this leads to problems such as software only being written to work with Wlroots based compositors or GNOME/KDE. From a developer's perspective, you can't just leave out GNOME because GNOME is incredibly popular and used by a very significant amount of GNU/Linux users, but at the same time if you leave out Wlroots based compositors a lot of power users aren't going to be able to use the software on their favorite compositor, so no power users are going to be using the software. So the developer has to support BOTH GNOME and Wlroots, and most likely also test on both Wlroots and GNOME, unless the program has a significant enough userbase. GNOME has a history of doing their own thing instead of following a standard, and making decisions that only benefit GNOME and no one else, which is likely why they implemented their own version of the Wayland protocol. Whether that's true or not doesn't matter, because right now there's no standard implementation of the Wayland protocol, leading to more work for the developer.

-

As you probably know, about two weeks ago I finished porting my program spmenu over to Wayland. While I was working on the port however, I almost immediately noticed how lacking Wayland really is in terms of features. They claim this is for "security", but I don't buy this argument for several reasons. spmenu has a feature to position itself at a specific X or Y position on the screen, but in the name of security wayland-client (the library used to create Wayland clients) does not allow you to do this. I ended up disabling this feature in the final product, which really should not have to be done. I get that this can't be done with a standard window, but this is a layer window, meaning it's supposed to be layered above all other windows, so it makes sense to allow it to be placed anywhere.

-

The reason I don't think security is a valid excuse here, is because with the wlr-layer-shell protocol you can grab the keyboard and (almost) all input, and grab the focus all to yourself. That's a much higher security risk than allowing the window to position itself anywhere. Instead of allowing a specific position, we instead have anchors, allowing us to anchor the window to a predefined part of the screen, such as top, bottom and center. Also, if you have programs doing malicious things by positioning itself, you have a much bigger problem. Wayland does do some things in the name of security that I think are somewhat justified, such as not allowing a client to move another client, or read keystrokes when the program isn't actually used. That's very useful for keylogging and other nasty things. But at the same time, if you have malware on your computer, then you have bigger problems than that, and there are legitimate uses for logging keys or moving other clients, which now aren't going to be possible anymore in the name of security.

-

Alright, so we've established that Wayland has fewer features than X11, how could things get any worse? GNOME has the answer to that. Because there's no standard implementation, you can just choose not to implement certain features. wlr-layer-shell is a unstable protocol, but despite this it's the only way to create a run launcher that functions like.. a run launcher, at least on the Wlroots implementation of Wayland. GNOME however doesn't implement wlr-layer-shell so any programs that use wlr-layer-shell will not function under GNOME, and spmenu is no exception to this. It doesn't make it any better that GNOME has a very high authority over the direction Wayland is going in, and really the direction GNU/Linux as a whole is going in.

-

Okay, but what's Wayland really like to use for the average user? Mixed, let's just say that. If you're using a desktop environment, chances are you don't even notice any difference between it and the same desktop environment on X11, at least none that isn't positive. If you're using a window manager on the other hand, you're going to notice things right away. Many programs that you may be using just will not function anymore, particularly the programs that capture the display. Wayland shills will claim that Wayland has support for all your X11 programs, but while that's not entirely false, anything that captures the screen itself is going to be totally broken on Wayland.

-

One thing I noticed fairly quickly is that screenshotting doesn't work. I'm using a tool called maim for this, and maim is X11 specific. Great, use XWayland right? XWayland doesn't work for this purpose, and as a result the capture is just black. What about ffmpeg and x11grab? Nope, doesn't work and all you get is a black screen. Turns out on Wayland you need Pipewire (or another tool) to capture the screen, and ffmpeg doesn't support this, so if you had plans of using Wayland and at the same time using ffmpeg to capture your screen, you're out of luck. While replacements for the X11 specific software does exist, much of it is very buggy, broken, not in repositories or just not the same thing. Recording using ffmpeg can be replaced using a command line utility called wf-recorder, but screenshots are little more complex.

-

On Arch, you need to manually compile a program called wayshot (a program that functions as a maim replacement) because the version you can get from the AUR is out of date and doesn't support using slurp (a slop replacement), meaning you can't select. After that though, everything works pretty much as expected. But what about copying the image to the clipboard? Well, on X11 we can just pipe the image into xclip -sel clipboard -t image/png, but as you might expect this isn't built to use Wayland natively. It does work, at least with XWayland compatible compositors but to do it natively you'll want a replacement called wl-clipboard and the wl-copy command. The wl-copy command works pretty much in the same way, pipe the image or text into it. Unlike with xclip though, you don't need to specify a type, and wl-copy only supports one clipboard so you don't need to specify a selection either.

-

Normal X11 programs though that run in a normal window or floating window usually work fine, and I was able to carry on using my X11 terminal emulator which is st just fine, with no noticeable loss in speed. No configuration is required for these to function with most compositors, although some don't support XWayland such as Qtile, so with those you may not be able to use your X11 specific programs.

-

What about Wayland compositors? Most of them are terrible in my experience. Maybe there's some secret awesome compositor, but every single one I have used so far has had some major flaw that makes it unusable. I started off my Wayland journey on Hyprland because I hear that's what most people use. The default keybinds are absolutely awful, and a good example of that is Super+q which doesn't quit Hyprland or close a window, but rather spawns Kitty, which isn't even a Wayland specific terminal emulator. Certainly a weird default. Even after some configuration though, Hyprland has several issues. For one, if you set a wallpaper using swaybg or hyprpaper the computer runs much slower, and Chromium seems to freeze at random. This happens with all my computers, with both Intel graphics and AMD graphics. I ended up determining that it was a problem with Hyprland because with dwl, sway and river everything worked perfectly with a wallpaper set. Most of these compositors also do not have a built in bar, sway is the only one I found that has one, not even dwl which is supposed to be a dwm clone has a built in bar, despite using way more lines of code than the original dwm.

-

Wayland has several issues as well that make the entire product completely unusable. For one, I have never been able to get it to work on my NVIDIA GPU (GTX 1060 6GB) system. Not with the free software driver and not with the nonfree nvidia driver. It's possible it works with GNOME or KDE, but I have no interest in running any of those, and I don't care for desktop environments. While it isn't fair to blame Wayland or Wlroots for this, in practice I'm unable to use Wayland on my NVIDIA system, and as such I decided it was worth mentioning.

-

By the way, I should also mention that I have implemented Wayland screen capturing into dfmpeg-spmenu and screenshot-spmenu if you want to use spmenu for screenshots or screen recording. This is also X11 compatible, so you don't need to switch script whenever you switch back to X11.

-

Anyways, I'm done with Wayland as of now. I will keep a session around to try out my own software in and will continue to support Wayland in spmenu, but I will not use Wayland anymore, and I am very happy to go back to dwm and X11. I may eventually make a second part to this blog post where I talk about actual code and programming in C for Wayland, but I'm going to end this blog post here. If you had an interesting experience with Wayland or thoughts on Wayland, feel free to share it with me. Thank you for reading, have a good day!

-
- - - - diff --git a/articles/post62.php b/articles/post62.php deleted file mode 100644 index 36a546f..0000000 --- a/articles/post62.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - -Distros need to stop promoting nonfree software - - - - - - -
-

Distros need to stop promoting nonfree software

-

2023-06-22

-

It is no secret that I can't stand the absolute state of the modern GNU/Linux desktop. Even putting all of that aside though, there are some other issues I want to talk about. I've talked a lot about package management, audio and more, but the biggest problem is how we (the community) approach the normies. Many of these easy distributions come with a graphical package manager. Fair enough if you're new, right? These package managers often have a "featured" section, I know PopOS has one, and that's where the problem lies. PopOS and likely other distributions are actively recommending nonfree software through the "featured" section.

-

That is a huge problem because by recommending nonfree software you are telling normies that they SHOULD continue to use nonfree software, and they should not adapt to our ideas and start using free software alternatives. I get that some nonfree software just does not have good free software replacements, but you as the distro maintainer need to be able to put your foot down, and stop recommending Google Chrome or Microsoft Office or LastPass or other nonfree software when there are clear free software alternatives that usually accomplish the same task, and usually does a better job at it too.

-

The solution: Nonfree software should not be recommended by the GNU/Linux community. There is no harm in keeping it available, if not intentionally making it a little bit harder to install, because some users just are not able to move away from it for many different reasons. But we should not make it as easy to install nonfree software as it is to install free software. When you install GNU/Linux, you should be encouraged to move away from nonfree software for the most part in favor of free software that respects the user's freedom and privacy. By recommending nonfree software, you are encouraging the user not to care about privacy, and use GNU/Linux because "it works better than Windows" rather than "I care about my privacy and security".

-

If you have read ploum.net's excellent article titled We need more of Richard Stallman, not less you're no doubt aware of this already, but the free software foundation has slowly been replaced by the more corporate friendly open source movement which doesn't care about your freedom, only the collaboration aspect of free software. These same people want Stallman and the Free Software Foundation gone, because they actively dislike free software. The thing is we NEED Stallman's extremist views on software. We need to go all out on free software, not just use SOME free software but mostly nonfree software, because if we don't we still have terribly privacy and security. And when a "faster" or "better" version of the free software comes out, why shouldn't we just use that instead?

-

The best way to spread free software and avoid spreading nonfree software is to promote free software, and shame nonfree software for not respecting users' freedom and privacy. Normies usually get into free software by using GNU/Linux, so there's an excellent opportunity to promote free software rather than nonfree software.

-

Let me know what you think. Do you think it's justified to promote nonfree software? Do you think we should be even more strict, maybe not even allow nonfree software in the main repositories? I'm interested to hear about it. Have a good day.

-
- - - - diff --git a/articles/post63.php b/articles/post63.php deleted file mode 100644 index 18137dd..0000000 --- a/articles/post63.php +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - -
-

Host your own services NOW!

-

2023-06-24

-

I talk a lot about freedom, privacy and free software on this blog, but today I want to talk about hosting your own services. But why should you host your own services? Isn't that really scary and difficult? Doesn't it require very powerful hardware? No, not really and I'm going to talk about some of the benefits here.

-

Alright so let's talk a bit about why you should host your own stuff and what you can host. There are many different services you can host. I'm hosting my website, some files, a Git server, wiki, email server and might host more in the future. But there are many cool things you can host, such as a Matrix homeserver, IRC network, SearX instance, PeerTube, NextCloud, it goes on and on. I won't be talking much about the specific services you can host today. But why should you host all of this stuff? Why not just use Gmail, or a public SearX instance, or GitHub, or any of these public services?

-

It's because as the sysadmin, you are very powerful and have a lot of power over your users and your services, and my site and services are no exception. You have power over everyone that uses your site and services. The ability to delete their accounts, look at what they're doing, all of these different things that you have no control over. When you host your own services though, the only one who is going to be able to see what you upload to your server is you (and your VPS provider if you're hosting using a VPS). Maybe other people can see it if they manage to compromise your server or you let your web server serve content that you don't want public. But in general, you're the only one who is going to be able to see that.

-

Let's take a public SearX instance for example. Let's say you visit searx.speedie.site and use it as your primary engine. Now, this search engine does not exist because I host my SearX instance locally but anyways, if you visit my SearX instance and use it to search for things, I have the power to log the search queries you search for, and I have the ability to see all the anime pornography you search for with great shame. Do you really trust me to not look at your search queries? No? So why should you trust any other SearX instance or hell, even Google for that matter. For this reason, you should take matters into your own hands and host your own services that you have control over. That way, you have the power to customize anything and everything about the service you're hosting, shut it down at any time to perform maintainence, set up logging, shred all logs and log absolutely nothing, etc.

-

But, doesn't hosting your own services require spending a lot of money? Doesn't it require a very powerful computer? No. If you want to host many, massive big files on a VPS or server that you rent, you may not have that much disk space. But even if that's the case you can host from home on a cheap old Dell Optiplex or maybe even a Raspberry Pi and just connect storage to it. I'm hosting a Git server using Gitea, and all the repositories Gitea handles combined only takes up approximately 870MB. And my public folder where I host downloads to all my software only takes up about 30MB. That really isn't much, and you can host that and much, much more on a cheap VPS. And the spmenu wiki I host takes up 31MB. So unless you want to host many, massive files I think making the argument that you don't have space is ridiculous. Any desktop computer from.. say 2008 or later is going to be able to handle hosting your site, and the terrible hard drive it has is going to be able to hold all of your files as well.

-

You can get a cheap VPS from Vultr for $3.50, and you can get a domain for usually very cheap as well. I went with Namecheap for my domain name, and they seem quite reliable and not very expensive. If you want to get a VPS from Vultr, feel free to use my referral link. There are other VPS companies though, and I still recommend hosting from home if you are able to, and your ISP reliably allows you to because it's likely still going to be a bit cheaper, but more importantly means you avoid the ability for your VPS provider to look at the contents of the virtual hard disk, and you are able to use more disk space. You have a lot more freedom that way. Still, a VPS is not a bad choice if you just want to host a few services and your personal site, but it's probably not the best option if you want to host NextCloud or a lot of big files or use it as a media server or anything like that. It also makes a lot more sense if you want to, for instance set up a VPN. Doing that on your own network doesn't make much sense unless you use the VPN away from home.

-

I won't get into hosting from home as that isn't something I'm familiar with (although I might try it at some point), and I also won't get into more complex setups or containers, just the basics. While I'm not a particularly big fan of Debian based GNU/Linux distributions, simply because of their old packages and the apt-get package manager, it's a fairly good choice if you want things to just work and serve your content all day every day. Despite not really liking Debian very much, it's what this website is hosted on, along with my other services I have.

-

When I'm using a VPS, I usually start by adding a new user and giving him a password. Then I usually install doas because it's smaller and has had fewer vulnerabilities than the more bloated sudo that people use. Then I will copy over my SSH keys to that user's .ssh directory. Finally, I always disable authentication using passwords for SSH, and more importantly I disable SSH as the root user. I do this because the root user is present on almost every machine, meaning if you want to gain access to someone's server by bruteforcing, a safe bet is to try to gain access using the root account. Then for extra security I will disable the actual root user, so the only way to gain superuser is to use doas. Now you may have to open ports to be able to host anything on it. If you want to host websites you will have to open TCP port 80 for HTTP and 443 for HTTPS. On Vultr VPSes this is done using the ufw command, which is the firewall the VPS comes with. It should be noted though, that if you want to host an email server you will need to open port 25 used for SMTP, and should be done with the ufw command as well, but you also need to file a ticket on Vultr's website giving a valid reason for wanting the port to be opened. Usually they will accept your request, though.

-

Now that you've opened the ports you need, you can start hosting the services you wish to host. I would probably install Apache and php-fpm for PHP to get my website set up now. A VPS is going to function exactly like any GNU/Linux computer you're used to, although it will not have a graphical environment. Therefore you should expect to get familiar with Vim, it is your best friend. Anyways, you should host your own services, instead of using public services because it's more private, more secure, and you have much more control than with a public service that many people are going to use.

-
- - - - diff --git a/blog.php b/blog.php index 957e819..1473aef 100644 --- a/blog.php +++ b/blog.php @@ -1,105 +1,295 @@ - - - - - -Blog posts - - - - - -
-

Blog

-

I repost some of my RSS feed articles/posts here sometimes. This is a view of all of them.

-

NOTE: You can see all of them using my RSS feed.

-

Latest blog post

-

Feeds

-

This is a list of feeds containing the complete list of blog posts. You can add any of these to your RSS reader and read at any time, provided you have an internet connection.

-

If you do not have a reader, install newsboat with your GNU/Linux distribution's package manager.

- -

Articles

-

Posts 60-69

-
Host your own services NOW!, written 2023-06-24
-
Distros need to stop promoting nonfree software, written 2023-06-22
-
The Wayland experience, written 2023-06-17
-
You don't need to justify your decisions., written 2023-06-08
-

Posts 50-59

-
Yet another update post., written 2023-06-03
-
Swedish man rants about licenses again, written 2023-05-23
-
Ungoogled Chromium: The best browser for most people, written 2023-05-01
-
Why I don't use Wayland (and how it can be improved), written 2023-04-28
-
Dear bloggers: Your RSS feeds suck., written 2023-04-19
-
News/important update regarding the site, written 2023-04-14
-
I switched back to Microsoft Windows.. here's why!, written 2023-04-01
-
Friendship ended with Gentoo, now Arch is my best friend!, written 2023-03-26
-
Important site update (and the Matrix), written 2023-03-15
-
Normies are destroying GNU/Linux, written 2023-03-09
-

Archived blog articles/posts

-

NOTE: Some of these have been archived due to lack of quality, others have been archived to keep the number of current posts low.

-

Posts 40-49

-
spDE - Now also on Arch based distros, written 2023-02-27
-
Software update, written 2023-02-25
-
Ethical software is not ethical and should be abolished., written 2023-02-07
-
libvirt is the worst program ever made.., written 2023-02-06
-
speedwm 1.9 release, written 2023-02-05
-
..and a git repository (CGIT REVIEW!!!), written 2023-01-28
-
speedie.site now has a wiki!, written 2023-01-26
-
When will I use BSD?, written 2023-01-17
-
Why YouTube©️™️ doesn't recommend your videos., written 2023-01-15
-
Let's talk about Project 081 0.6, written 2023-01-03
-

Posts 37-39

-
Goodbye 2022.., written 2022-12-31
-
I WILL make music great again. (My next project), written 2022-12-20
-
How I got into GNU/Linux, written 2022-12-13
-

Posts 30-36

-
I use Chromium based browsers again. (How to lose your followers in less than 5 minutes), written 2022-11-30
-
speedwm 1.5: It's still speedwm., written 2022-11-28
-
We're back up better than ever! (feat. OpenBaSeD), written 2022-11-25
-
Forwarder Factory is over. (Please read the blog articles/post), written 2022-10-26
-
Please give me suggestions..., written 2022-10-10
-
I HATE NONFREE SOFTWARE (install gnu icecat), written 2022-09-23
-

Posts 20-29

-
RIP in peace rchat (and releasing its replacement), written 2022-09-21
-
SHILL POSTS ARE BACK! fontctrl (Fonts on GNU/Linux-Improved), written 2022-09-17
-
I AM TOO AWESOME FOR SMARTPHONES!, written 2022-09-15
-
Vim: You're wasting your life away if you don't use it., written 2022-09-04
-
I left GitHub and you should too!, written 2022-08-23
-
What happened to spDE? (And announcement), written 2022-07-23
-
Why I ban software., written 2022-07-20
-
OH NO IM BEING CANCELLED ON TWITTER WHAT WILL I DO???, written 2022-07-14
-
PipeWire Review (RSS REVIEWS!!!), written 2022-07-04
-
rchat 1.3 is out! (I AM GREAT AT PUSHING UPDATES!), written 2022-06-29
-

Posts 10-19

-
dwm: dynamic window greatness!, written 2022-06-18
-
I HATE ATI!!!, written 2022-06-18
-
Website update, written 2022-06-10
-
Return of the rchat (rchat 1.0 is out), written 2022-06-07
-
Are GNU/Linux users elitist or are normies too stupid to learn?, written 2022-06-06
-
Why I switched license from MIT to GPLv3, written 2022-06-05
-
Open source: Fake freedom., written 2022-06-05
-
I HATE APPLE!!!, written 2022-05-23
-
Why I don't support RiiConnect24., written 2022-05-20
-
Smartphones are only smart because you're dumb., written 2022-05-04
-
xinit is bloated, written 2022-04-30
-

Post 1-9

-
Everything I want to use is Chromium, written 2022-04-26
-
Half an rchat (rchat 0.5 is out), written 2022-04-26
-
rchat 0.4 is here (Now available on Arch and Gentoo), written 2022-04-24
-
It's time to stop using Adblock Plus (seriously stop), written 2022-03-12
-
Happy 20th Birthday Arch!, written 2022-03-11
-
What you can expect from Project 081 0.6, written 2022-03-10
-
Dear soydevs: Stop making desktop applications bloated, written 2022-03-10
-
Notice for spDE users, written 2022-03-09
-
Stop making GNU/Linux user friendly.. sort of, written 2022-03-09
-
- - - + + * Copyright (C) 2023 speedie + * + * See LICENSE file for copyright and license details. + */ + +spl_autoload_register(function($class){ + require str_replace('\\', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php'; +}); + +use md\MarkdownExtra; + +define('BLOG_PATH', dirname(__FILE__). '/articles'); + +define('BLOG_EXT', 'md'); +define('BASE_URI', str_replace('/index.php', '', $_SERVER['SCRIPT_NAME'])); + +define('SELF', $_SERVER['SCRIPT_NAME']); +define('VIEW', ''); // '?action=view&page=' + +define('ENABLE_TITLE', true); +define('ENABLE_HEAD', true); +define('ENABLE_FOOTER', true); + +define('META_DESC', true); +define('META_ENC', true); + +define('TITLE_DATE', 'j M Y'); + +function __( $label, $alt_word = null ) { + return is_null($alt_word) ? $label : $alt_word; +} + +function truncate($text, $chars) { + if (strlen($text) <= $chars) { + return $text; + } + $text = $text." "; + $text = substr($text,0,$chars); + $text = substr($text,0,strrpos($text,' ')); + $text = $text."..."; + return $text; +} + +function printHeader($title, $action, $html) { + // TODO: Improve this garbage, I suck at PHP and this is just stuff I found on the internet. + if (META_DESC) { + $nhtml = $html; + $nhtml = preg_replace( '@]*>(?=.*?]*>).*?<\@p>@si', '', $nhtml); + $nhtml = preg_replace( '@<(li)[^>]*?>.*?@si', '', $nhtml); + $nhtml = preg_replace( '@<(ul)[^>]*?>.*?@si', '', $nhtml); + $nhtml = strip_tags($nhtml); + $nhtml = preg_replace('/\s*$^\s*/m', "\n", $nhtml); + $nhtml = truncate($nhtml, 512); + } + + print "\n"; + print "\n"; + + if (ENABLE_HEAD) { + print " \n"; + + if (META_ENC) { + print " \n"; + } + + if (META_DESC && $action != 'home') { + print " \n"; + } + + if (ENABLE_TITLE) { + print " $title\n"; + } + + include("php/header.php"); + + print " \n"; + } + + print " \n"; + + if ($action === 'home') { + include("php/blog-p.php"); + } +} + +function printFooter() { + if (ENABLE_FOOTER) { + print " \n"; + + include("php/footer.php"); + } +} + +function getDateForPage($pageName, $date_format, $pageDate) { + $file = BLOG_PATH . "/$pageName." . BLOG_EXT . ".date"; + + if (file_exists($file)) { + return file_get_contents($file); + } else { + return date($date_format, $pageDate); + } +} + +function descLengthSort($val_1, $val_2) { + $firstVal = strlen($val_1); + $secondVal = strlen($val_2); + return ( $firstVal > $secondVal ) ? + -1 : ( ( $firstVal < $secondVal ) ? 1 : 0); +} + +function getAllPageNames($path = "") { + $filenames = array(); + $dir = opendir(BLOG_PATH . "/$path" ); + + while ( $filename = readdir($dir) ) { + if ( $filename[0] == "." ) { + continue; + } + + if ( is_dir( BLOG_PATH . "/$path/$filename" ) ) { + array_push($filenames, ...getAllPageNames( "$path/$filename" ) ); + continue; + } + + if ( preg_match("/".BLOG_EXT."$/", $filename) != 1) { + continue; + } + + $filename = substr($filename, 0, -(strlen(BLOG_EXT)+1) ); + $filenames[] = substr("$path/$filename", 1); + } + closedir($dir); + return $filenames; +} + +function fileNameForPage($page) { + return BLOG_PATH . "/$page." . BLOG_EXT; +} + +function dateForPage($page) { + $file = BLOG_PATH . "/$page." . BLOG_EXT . ".date"; + + if (!file_exists($file)) { + return filectime(BLOG_PATH . "/$page." . BLOG_EXT); + } else { + return file_get_contents($file); + } +} + +function numForPage($page) { + $file = BLOG_PATH . "/$page." . BLOG_EXT . ".num"; + + return file_get_contents($file); +} + +function sanitizeFilename($inFileName) { + return str_replace(array('~', '..', '\\', ':', '|', '&'), '-', $inFileName); +} + +function pageURL($page) { + return SELF . VIEW . "/".str_replace("%2F", "/", str_replace("%23", "#", urlencode(sanitizeFilename($page)))); +} + +function pageLink($page, $title, $attributes="") { + return "$title"; +} + +function redirectWithMessage($page, $msg) { + $_SESSION["msg"] = $msg; + header("HTTP/1.1 303 See Other"); + header("Location: " . pageURL($page) ); + exit; +} + +function checkedExecute(&$msg, $cmd) { + $returnValue = 0; + $output = ''; + exec($cmd, $output, $returnValue); + + if ($returnValue != 0) { + $msg .= "
Error executing command ".$cmd." (return value: ".$returnValue."): ".implode(" ", $output); + } + + return ($returnValue == 0); +} + +function toHTMLID($noid) { + return str_replace(" ", "-", $noid); +} + +function toHTML($inText) { + $parser = new MarkdownExtra; + $parser->no_markup = true; + $outHTML = $parser->transform($inText); + + preg_match_all("/\[\[(.*?)\]\]/", $outHTML, $matches, PREG_PATTERN_ORDER); + + for ($i = 0; $i < count($matches[0]); $i++) { + $fullLinkText = $matches[1][$i]; + $linkTitleSplit = explode('|', $fullLinkText); + $linkedPage = $linkTitleSplit[0]; // split away an eventual link text + $linkText = (count($linkTitleSplit) > 1) ? $linkTitleSplit[1] : $linkedPage; + $pagePart = explode('#', $linkedPage)[0]; // split away an eventual anchor part + $linkedFilename = fileNameForPage(sanitizeFilename($pagePart)); + $exists = file_exists($linkedFilename); + $outHTML = str_replace("[[$fullLinkText]]", + pageLink($linkedPage, $linkText, ($exists? "" : " class=\"noexist\"")), $outHTML); + } + + $outHTML = preg_replace("/\{\{(.*?)\}\}/", "\"\\1\"", $outHTML); + + preg_match_all("/(.*?)<\/h\\1>/", $outHTML, $matches, PREG_PATTERN_ORDER); + + for ($i = 0; $i < count($matches[0]); $i++) { + $prefix = ""; + $caption = $matches[2][$i]; + $suffix = substr_replace($prefix, "/", 1, 0); + $outHTML = str_replace("$prefix$caption$suffix", + "$prefix$caption$suffix", $outHTML); + } + + return $outHTML; +} + +$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'view'; +$newPage = ""; +$text = ""; +$html = ""; + +if ($action === 'view') { + $page = preg_match('@^/@', @$_SERVER["PATH_INFO"]) ? + urldecode(substr($_SERVER["PATH_INFO"], 1)) : urldecode(@$_REQUEST['page']); + $page = sanitizeFilename($page); + + if ($page != '') { + $filename = fileNameForPage($page); + + if ( file_exists($filename) ) { + $text = file_get_contents($filename); + } else { + $newPage = NULL; + include('php/404.php'); + die(); + } + } else { + $action = 'home'; + } +} + +if ( $action === 'home') { + $pageNames = getAllPageNames(); + $filelist = array(); + $sortBy = isset($_REQUEST['sortBy']) ? $_REQUEST['sortBy'] : 'name'; + + foreach($pageNames as $page) { + $filelist[$page] = numForPage($page); + } + + arsort($filelist, SORT_NUMERIC); + + // Page list + $date_format = __('date_format', TITLE_DATE); + + foreach ($filelist as $pageName => $pageDate) { + $html .= "

".pageLink($pageName, $pageName).", written ".getDateForPage($pageName, $date_format, $pageDate)."

\n"; + } +} else { // convert the page and view it + $html .= empty($text) ? '' : toHTML($text); +} + +// All blog posts +$datetime = ''; +if (($action === 'home')) { + $title = __("Blog posts"); +} else if ($filename != '') { + $title = $page; + $date_format = __('date_format', TITLE_DATE); + + if ( $date_format ) { + $datetime = "" . date($date_format, @filectime($filename)) . ""; + } +} + +// print text +printHeader($title, $action, $html); +print "
\n\n"; +print "$html\n"; +print "
\n"; +print " \n"; +printFooter(); diff --git a/md/Markdown.inc.php b/md/Markdown.inc.php new file mode 100755 index 0000000..e2bd380 --- /dev/null +++ b/md/Markdown.inc.php @@ -0,0 +1,10 @@ + + * @copyright 2004-2019 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + +namespace md; + +/** + * Markdown Parser Class + */ +class Markdown implements MarkdownInterface { + /** + * Define the package version + * @var string + */ + const MARKDOWNLIB_VERSION = "1.9.0"; + + /** + * Simple function interface - Initialize the parser and return the result + * of its transform method. This will work fine for derived classes too. + * + * @api + * + * @param string $text + * @return string + */ + public static function defaultTransform($text) { + // Take parser class on which this function was called. + $parser_class = \get_called_class(); + + // Try to take parser from the static parser list + static $parser_list; + $parser =& $parser_list[$parser_class]; + + // Create the parser it not already set + if (!$parser) { + $parser = new $parser_class; + } + + // Transform text using parser. + return $parser->transform($text); + } + + /** + * Configuration variables + */ + + /** + * Change to ">" for HTML output. + * @var string + */ + public $empty_element_suffix = " />"; + + /** + * The width of indentation of the output markup + * @var int + */ + public $tab_width = 4; + + /** + * Change to `true` to disallow markup or entities. + * @var boolean + */ + public $no_markup = false; + public $no_entities = false; + + + /** + * Change to `true` to enable line breaks on \n without two trailling spaces + * @var boolean + */ + public $hard_wrap = false; + + /** + * Predefined URLs and titles for reference links and images. + * @var array + */ + public $predef_urls = array(); + public $predef_titles = array(); + + /** + * Optional filter function for URLs + * @var callable|null + */ + public $url_filter_func = null; + + /** + * Optional header id="" generation callback function. + * @var callable|null + */ + public $header_id_func = null; + + /** + * Optional function for converting code block content to HTML + * @var callable|null + */ + public $code_block_content_func = null; + + /** + * Optional function for converting code span content to HTML. + * @var callable|null + */ + public $code_span_content_func = null; + + /** + * Class attribute to toggle "enhanced ordered list" behaviour + * setting this to true will allow ordered lists to start from the index + * number that is defined first. + * + * For example: + * 2. List item two + * 3. List item three + * + * Becomes: + *
    + *
  1. List item two
  2. + *
  3. List item three
  4. + *
+ * + * @var bool + */ + public $enhanced_ordered_list = false; + + /** + * Parser implementation + */ + + /** + * Regex to match balanced [brackets]. + * Needed to insert a maximum bracked depth while converting to PHP. + * @var int + */ + protected $nested_brackets_depth = 6; + protected $nested_brackets_re; + + protected $nested_url_parenthesis_depth = 4; + protected $nested_url_parenthesis_re; + + /** + * Table of hash values for escaped characters: + * @var string + */ + protected $escape_chars = '\`*_{}[]()>#+-.!'; + protected $escape_chars_re; + + /** + * Constructor function. Initialize appropriate member variables. + * @return void + */ + public function __construct() { + $this->_initDetab(); + $this->prepareItalicsAndBold(); + + $this->nested_brackets_re = + str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). + str_repeat('\])*', $this->nested_brackets_depth); + + $this->nested_url_parenthesis_re = + str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). + str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); + + $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; + + // Sort document, block, and span gamut in ascendent priority order. + asort($this->document_gamut); + asort($this->block_gamut); + asort($this->span_gamut); + } + + + /** + * Internal hashes used during transformation. + * @var array + */ + protected $urls = array(); + protected $titles = array(); + protected $html_hashes = array(); + + /** + * Status flag to avoid invalid nesting. + * @var boolean + */ + protected $in_anchor = false; + + /** + * Status flag to avoid invalid nesting. + * @var boolean + */ + protected $in_emphasis_processing = false; + + /** + * Called before the transformation process starts to setup parser states. + * @return void + */ + protected function setup() { + // Clear global hashes. + $this->urls = $this->predef_urls; + $this->titles = $this->predef_titles; + $this->html_hashes = array(); + $this->in_anchor = false; + $this->in_emphasis_processing = false; + } + + /** + * Called after the transformation process to clear any variable which may + * be taking up memory unnecessarly. + * @return void + */ + protected function teardown() { + $this->urls = array(); + $this->titles = array(); + $this->html_hashes = array(); + } + + /** + * Main function. Performs some preprocessing on the input text and pass + * it through the document gamut. + * + * @api + * + * @param string $text + * @return string + */ + public function transform($text) { + $this->setup(); + + # Remove UTF-8 BOM and marker character in input, if present. + $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); + + # Standardize line endings: + # DOS to Unix and Mac to Unix + $text = preg_replace('{\r\n?}', "\n", $text); + + # Make sure $text ends with a couple of newlines: + $text .= "\n\n"; + + # Convert all tabs to spaces. + $text = $this->detab($text); + + # Turn block-level HTML blocks into hash entries + $text = $this->hashHTMLBlocks($text); + + # Strip any lines consisting only of spaces and tabs. + # This makes subsequent regexen easier to write, because we can + # match consecutive blank lines with /\n+/ instead of something + # contorted like /[ ]*\n+/ . + $text = preg_replace('/^[ ]+$/m', '', $text); + + # Run document gamut methods. + foreach ($this->document_gamut as $method => $priority) { + $text = $this->$method($text); + } + + $this->teardown(); + + return $text . "\n"; + } + + /** + * Define the document gamut + * @var array + */ + protected $document_gamut = array( + // Strip link definitions, store in hashes. + "stripLinkDefinitions" => 20, + "runBasicBlockGamut" => 30, + ); + + /** + * Strips link definitions from text, stores the URLs and titles in + * hash references + * @param string $text + * @return string + */ + protected function stripLinkDefinitions($text) { + + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: ^[id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 + [ ]* + \n? # maybe *one* newline + [ ]* + (?: + <(.+?)> # url = $2 + | + (\S+?) # url = $3 + ) + [ ]* + \n? # maybe one newline + [ ]* + (?: + (?<=\s) # lookbehind for whitespace + ["(] + (.*?) # title = $4 + [")] + [ ]* + )? # title is optional + (?:\n+|\Z) + }xm', + array($this, '_stripLinkDefinitions_callback'), + $text + ); + return $text; + } + + /** + * The callback to strip link definitions + * @param array $matches + * @return string + */ + protected function _stripLinkDefinitions_callback($matches) { + $link_id = strtolower($matches[1]); + $url = $matches[2] == '' ? $matches[3] : $matches[2]; + $this->urls[$link_id] = $url; + $this->titles[$link_id] =& $matches[4]; + return ''; // String that will replace the block + } + + /** + * Hashify HTML blocks + * @param string $text + * @return string + */ + protected function hashHTMLBlocks($text) { + if ($this->no_markup) { + return $text; + } + + $less_than_tab = $this->tab_width - 1; + + /** + * Hashify HTML blocks: + * + * We only want to do this for block-level HTML tags, such as headers, + * lists, and tables. That's because we still want to wrap

s around + * "paragraphs" that are wrapped in non-block-level tags, such as + * anchors, phrase emphasis, and spans. The list of tags we're looking + * for is hard-coded: + * + * * List "a" is made of tags which can be both inline or block-level. + * These will be treated block-level when the start tag is alone on + * its line, otherwise they're not matched here and will be taken as + * inline later. + * * List "b" is made of tags which are always block-level; + */ + $block_tags_a_re = 'ins|del'; + $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. + 'script|noscript|style|form|fieldset|iframe|math|svg|'. + 'article|section|nav|aside|hgroup|header|footer|'. + 'figure|details|summary'; + + // Regular expression for the content of a block tag. + $nested_tags_level = 4; + $attr = ' + (?> # optional tag attributes + \s # starts with whitespace + (?> + [^>"/]+ # text outside quotes + | + /+(?!>) # slash not followed by ">" + | + "[^"]*" # text inside double quotes (tolerate ">") + | + \'[^\']*\' # text inside single quotes (tolerate ">") + )* + )? + '; + $content = + str_repeat(' + (?> + [^<]+ # content without tag + | + <\2 # nested opening tag + '.$attr.' # attributes + (?> + /> + | + >', $nested_tags_level). // end of opening tag + '.*?'. // last level nested tag content + str_repeat(' + # closing nested tag + ) + | + <(?!/\2\s*> # other tags with a different name + ) + )*', + $nested_tags_level); + $content2 = str_replace('\2', '\3', $content); + + /** + * First, look for nested blocks, e.g.: + *

+ *
+ * tags for inner block must be indented. + *
+ *
+ * + * The outermost tags must start at the left margin for this to match, + * and the inner nested divs must be indented. + * We need to do this before the next, more liberal match, because the + * next match will start at the first `
` and stop at the + * first `
`. + */ + $text = preg_replace_callback('{(?> + (?> + (?<=\n) # Starting on its own line + | # or + \A\n? # the at beginning of the doc + ) + ( # save in $1 + + # Match from `\n` to `\n`, handling nested tags + # in between. + + [ ]{0,'.$less_than_tab.'} + <('.$block_tags_b_re.')# start tag = $2 + '.$attr.'> # attributes followed by > and \n + '.$content.' # content, support nesting + # the matching end tag + [ ]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + + | # Special version for tags of group a. + + [ ]{0,'.$less_than_tab.'} + <('.$block_tags_a_re.')# start tag = $3 + '.$attr.'>[ ]*\n # attributes followed by > + '.$content2.' # content, support nesting + # the matching end tag + [ ]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + + | # Special case just for
. It was easier to make a special + # case than to make the other regex more complicated. + + [ ]{0,'.$less_than_tab.'} + <(hr) # start tag = $2 + '.$attr.' # attributes + /?> # the matching end tag + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + | # Special case for standalone HTML comments: + + [ ]{0,'.$less_than_tab.'} + (?s: + + ) + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + | # PHP and ASP-style processor instructions ( + ) + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + ) + )}Sxmi', + array($this, '_hashHTMLBlocks_callback'), + $text + ); + + return $text; + } + + /** + * The callback for hashing HTML blocks + * @param string $matches + * @return string + */ + protected function _hashHTMLBlocks_callback($matches) { + $text = $matches[1]; + $key = $this->hashBlock($text); + return "\n\n$key\n\n"; + } + + /** + * Called whenever a tag must be hashed when a function insert an atomic + * element in the text stream. Passing $text to through this function gives + * a unique text-token which will be reverted back when calling unhash. + * + * The $boundary argument specify what character should be used to surround + * the token. By convension, "B" is used for block elements that needs not + * to be wrapped into paragraph tags at the end, ":" is used for elements + * that are word separators and "X" is used in the general case. + * + * @param string $text + * @param string $boundary + * @return string + */ + protected function hashPart($text, $boundary = 'X') { + // Swap back any tag hash found in $text so we do not have to `unhash` + // multiple times at the end. + $text = $this->unhash($text); + + // Then hash the block. + static $i = 0; + $key = "$boundary\x1A" . ++$i . $boundary; + $this->html_hashes[$key] = $text; + return $key; // String that will replace the tag. + } + + /** + * Shortcut function for hashPart with block-level boundaries. + * @param string $text + * @return string + */ + protected function hashBlock($text) { + return $this->hashPart($text, 'B'); + } + + /** + * Define the block gamut - these are all the transformations that form + * block-level tags like paragraphs, headers, and list items. + * @var array + */ + protected $block_gamut = array( + "doHeaders" => 10, + "doHorizontalRules" => 20, + "doLists" => 40, + "doCodeBlocks" => 50, + "doBlockQuotes" => 60, + ); + + /** + * Run block gamut tranformations. + * + * We need to escape raw HTML in Markdown source before doing anything + * else. This need to be done for each block, and not only at the + * begining in the Markdown function since hashed blocks can be part of + * list items and could have been indented. Indented blocks would have + * been seen as a code block in a previous pass of hashHTMLBlocks. + * + * @param string $text + * @return string + */ + protected function runBlockGamut($text) { + $text = $this->hashHTMLBlocks($text); + return $this->runBasicBlockGamut($text); + } + + /** + * Run block gamut tranformations, without hashing HTML blocks. This is + * useful when HTML blocks are known to be already hashed, like in the first + * whole-document pass. + * + * @param string $text + * @return string + */ + protected function runBasicBlockGamut($text) { + + foreach ($this->block_gamut as $method => $priority) { + $text = $this->$method($text); + } + + // Finally form paragraph and restore hashed blocks. + $text = $this->formParagraphs($text); + + return $text; + } + + /** + * Convert horizontal rules + * @param string $text + * @return string + */ + protected function doHorizontalRules($text) { + return preg_replace( + '{ + ^[ ]{0,3} # Leading space + ([-*_]) # $1: First marker + (?> # Repeated marker group + [ ]{0,2} # Zero, one, or two spaces. + \1 # Marker character + ){2,} # Group repeated at least twice + [ ]* # Tailing spaces + $ # End of line. + }mx', + "\n".$this->hashBlock("empty_element_suffix")."\n", + $text + ); + } + + /** + * These are all the transformations that occur *within* block-level + * tags like paragraphs, headers, and list items. + * @var array + */ + protected $span_gamut = array( + // Process character escapes, code spans, and inline HTML + // in one shot. + "parseSpan" => -30, + // Process anchor and image tags. Images must come first, + // because ![foo][f] looks like an anchor. + "doImages" => 10, + "doAnchors" => 20, + // Make links out of things like `` + // Must come after doAnchors, because you can use < and > + // delimiters in inline links like [this](). + "doAutoLinks" => 30, + "encodeAmpsAndAngles" => 40, + "doItalicsAndBold" => 50, + "doHardBreaks" => 60, + ); + + /** + * Run span gamut transformations + * @param string $text + * @return string + */ + protected function runSpanGamut($text) { + foreach ($this->span_gamut as $method => $priority) { + $text = $this->$method($text); + } + + return $text; + } + + /** + * Do hard breaks + * @param string $text + * @return string + */ + protected function doHardBreaks($text) { + if ($this->hard_wrap) { + return preg_replace_callback('/ *\n/', + array($this, '_doHardBreaks_callback'), $text); + } else { + return preg_replace_callback('/ {2,}\n/', + array($this, '_doHardBreaks_callback'), $text); + } + } + + /** + * Trigger part hashing for the hard break (callback method) + * @param array $matches + * @return string + */ + protected function _doHardBreaks_callback($matches) { + return $this->hashPart("empty_element_suffix\n"); + } + + /** + * Turn Markdown link shortcuts into XHTML tags. + * @param string $text + * @return string + */ + protected function doAnchors($text) { + if ($this->in_anchor) { + return $text; + } + $this->in_anchor = true; + + // First, handle reference-style links: [link text] [id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ('.$this->nested_brackets_re.') # link text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + // Next, inline-style links: [link text](url "optional title") + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ('.$this->nested_brackets_re.') # link text = $2 + \] + \( # literal paren + [ \n]* + (?: + <(.+?)> # href = $3 + | + ('.$this->nested_url_parenthesis_re.') # href = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # Title = $7 + \6 # matching quote + [ \n]* # ignore any spaces/tabs between closing quote and ) + )? # title is optional + \) + ) + }xs', + array($this, '_doAnchors_inline_callback'), $text); + + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link text][1] + // or [link text](/foo) + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ([^\[\]]+) # link text = $2; can\'t contain [ or ] + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + $this->in_anchor = false; + return $text; + } + + /** + * Callback method to parse referenced anchors + * @param string $matches + * @return string + */ + protected function _doAnchors_reference_callback($matches) { + $whole_match = $matches[1]; + $link_text = $matches[2]; + $link_id =& $matches[3]; + + if ($link_id == "") { + // for shortcut links like [this][] or [this]. + $link_id = $link_text; + } + + // lower-case and turn embedded newlines into spaces + $link_id = strtolower($link_id); + $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); + + if (isset($this->urls[$link_id])) { + $url = $this->urls[$link_id]; + $url = $this->encodeURLAttribute($url); + + $result = "titles[$link_id] ) ) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + $result = $this->hashPart($result); + } else { + $result = $whole_match; + } + return $result; + } + + /** + * Callback method to parse inline anchors + * @param string $matches + * @return string + */ + protected function _doAnchors_inline_callback($matches) { + $link_text = $this->runSpanGamut($matches[2]); + $url = $matches[3] === '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + + // If the URL was of the form it got caught by the HTML + // tag parser and hashed. Need to reverse the process before using + // the URL. + $unhashed = $this->unhash($url); + if ($unhashed !== $url) + $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); + + $url = $this->encodeURLAttribute($url); + + $result = "encodeAttribute($title); + $result .= " title=\"$title\""; + } + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + + return $this->hashPart($result); + } + + /** + * Turn Markdown image shortcuts into tags. + * @param string $text + * @return string + */ + protected function doImages($text) { + // First, handle reference-style labeled images: ![alt text][id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + ('.$this->nested_brackets_re.') # alt text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + + ) + }xs', + array($this, '_doImages_reference_callback'), $text); + + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + ('.$this->nested_brackets_re.') # alt text = $2 + \] + \s? # One optional whitespace character + \( # literal paren + [ \n]* + (?: + <(\S*)> # src url = $3 + | + ('.$this->nested_url_parenthesis_re.') # src url = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # title = $7 + \6 # matching quote + [ \n]* + )? # title is optional + \) + ) + }xs', + array($this, '_doImages_inline_callback'), $text); + + return $text; + } + + /** + * Callback to parse references image tags + * @param array $matches + * @return string + */ + protected function _doImages_reference_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $link_id = strtolower($matches[3]); + + if ($link_id == "") { + $link_id = strtolower($alt_text); // for shortcut links like ![this][]. + } + + $alt_text = $this->encodeAttribute($alt_text); + if (isset($this->urls[$link_id])) { + $url = $this->encodeURLAttribute($this->urls[$link_id]); + $result = "\"$alt_text\"";titles[$link_id])) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + $result .= $this->empty_element_suffix; + $result = $this->hashPart($result); + } else { + // If there's no such link ID, leave intact: + $result = $whole_match; + } + + return $result; + } + + /** + * Callback to parse inline image tags + * @param array $matches + * @return string + */ + protected function _doImages_inline_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + + $alt_text = $this->encodeAttribute($alt_text); + $url = $this->encodeURLAttribute($url); + $result = "\"$alt_text\"";encodeAttribute($title); + $result .= " title=\"$title\""; // $title already quoted + } + $result .= $this->empty_element_suffix; + + return $this->hashPart($result); + } + + /** + * Parse Markdown heading elements to HTML + * @param string $text + * @return string + */ + protected function doHeaders($text) { + /** + * Setext-style headers: + * Header 1 + * ======== + * + * Header 2 + * -------- + */ + $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', + array($this, '_doHeaders_callback_setext'), $text); + + /** + * atx-style headers: + * # Header 1 + * ## Header 2 + * ## Header 2 with closing hashes ## + * ... + * ###### Header 6 + */ + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]* + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + \n+ + }xm', + array($this, '_doHeaders_callback_atx'), $text); + + return $text; + } + + /** + * Setext header parsing callback + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_setext($matches) { + // Terrible hack to check we haven't found an empty list item. + if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) { + return $matches[0]; + } + + $level = $matches[2][0] == '=' ? 1 : 2; + + // ID attribute generation + $idAtt = $this->_generateIdFromHeaderValue($matches[1]); + + $block = "".$this->runSpanGamut($matches[1]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * ATX header parsing callback + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_atx($matches) { + // ID attribute generation + $idAtt = $this->_generateIdFromHeaderValue($matches[2]); + + $level = strlen($matches[1]); + $block = "".$this->runSpanGamut($matches[2]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * If a header_id_func property is set, we can use it to automatically + * generate an id attribute. + * + * This method returns a string in the form id="foo", or an empty string + * otherwise. + * @param string $headerValue + * @return string + */ + protected function _generateIdFromHeaderValue($headerValue) { + if (!is_callable($this->header_id_func)) { + return ""; + } + + $idValue = call_user_func($this->header_id_func, $headerValue); + if (!$idValue) { + return ""; + } + + return ' id="' . $this->encodeAttribute($idValue) . '"'; + } + + /** + * Form HTML ordered (numbered) and unordered (bulleted) lists. + * @param string $text + * @return string + */ + protected function doLists($text) { + $less_than_tab = $this->tab_width - 1; + + // Re-usable patterns to match list item bullets and number markers: + $marker_ul_re = '[*+-]'; + $marker_ol_re = '\d+[\.]'; + + $markers_relist = array( + $marker_ul_re => $marker_ol_re, + $marker_ol_re => $marker_ul_re, + ); + + foreach ($markers_relist as $marker_re => $other_marker_re) { + // Re-usable pattern to match any entirel ul or ol list: + $whole_list_re = ' + ( # $1 = whole list + ( # $2 + ([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces + ('.$marker_re.') # $4 = first list item marker + [ ]+ + ) + (?s:.+?) + ( # $5 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another list item marker + [ ]* + '.$marker_re.'[ ]+ + ) + | + (?= # Lookahead for another kind of list + \n + \3 # Must have the same indentation + '.$other_marker_re.'[ ]+ + ) + ) + ) + '; // mx + + // We use a different prefix before nested lists than top-level lists. + //See extended comment in _ProcessListItems(). + + if ($this->list_level) { + $text = preg_replace_callback('{ + ^ + '.$whole_list_re.' + }mx', + array($this, '_doLists_callback'), $text); + } else { + $text = preg_replace_callback('{ + (?:(?<=\n)\n|\A\n?) # Must eat the newline + '.$whole_list_re.' + }mx', + array($this, '_doLists_callback'), $text); + } + } + + return $text; + } + + /** + * List parsing callback + * @param array $matches + * @return string + */ + protected function _doLists_callback($matches) { + // Re-usable patterns to match list item bullets and number markers: + $marker_ul_re = '[*+-]'; + $marker_ol_re = '\d+[\.]'; + $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; + $marker_ol_start_re = '[0-9]+'; + + $list = $matches[1]; + $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol"; + + $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re ); + + $list .= "\n"; + $result = $this->processListItems($list, $marker_any_re); + + $ol_start = 1; + if ($this->enhanced_ordered_list) { + // Get the start number for ordered list. + if ($list_type == 'ol') { + $ol_start_array = array(); + $ol_start_check = preg_match("/$marker_ol_start_re/", $matches[4], $ol_start_array); + if ($ol_start_check){ + $ol_start = $ol_start_array[0]; + } + } + } + + if ($ol_start > 1 && $list_type == 'ol'){ + $result = $this->hashBlock("<$list_type start=\"$ol_start\">\n" . $result . ""); + } else { + $result = $this->hashBlock("<$list_type>\n" . $result . ""); + } + return "\n". $result ."\n\n"; + } + + /** + * Nesting tracker for list levels + * @var integer + */ + protected $list_level = 0; + + /** + * Process the contents of a single ordered or unordered list, splitting it + * into individual list items. + * @param string $list_str + * @param string $marker_any_re + * @return string + */ + protected function processListItems($list_str, $marker_any_re) { + /** + * The $this->list_level global keeps track of when we're inside a list. + * Each time we enter a list, we increment it; when we leave a list, + * we decrement. If it's zero, we're not in a list anymore. + * + * We do this because when we're not inside a list, we want to treat + * something like this: + * + * I recommend upgrading to version + * 8. Oops, now this line is treated + * as a sub-list. + * + * As a single paragraph, despite the fact that the second line starts + * with a digit-period-space sequence. + * + * Whereas when we're inside a list (or sub-list), that line will be + * treated as the start of a sub-list. What a kludge, huh? This is + * an aspect of Markdown's syntax that's hard to parse perfectly + * without resorting to mind-reading. Perhaps the solution is to + * change the syntax rules such that sub-lists must start with a + * starting cardinal number; e.g. "1." or "a.". + */ + $this->list_level++; + + // Trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + $list_str = preg_replace_callback('{ + (\n)? # leading line = $1 + (^[ ]*) # leading whitespace = $2 + ('.$marker_any_re.' # list marker and space = $3 + (?:[ ]+|(?=\n)) # space only required if item is not empty + ) + ((?s:.*?)) # list item text = $4 + (?:(\n+(?=\n))|\n) # tailing blank line = $5 + (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n)))) + }xm', + array($this, '_processListItems_callback'), $list_str); + + $this->list_level--; + return $list_str; + } + + /** + * List item parsing callback + * @param array $matches + * @return string + */ + protected function _processListItems_callback($matches) { + $item = $matches[4]; + $leading_line =& $matches[1]; + $leading_space =& $matches[2]; + $marker_space = $matches[3]; + $tailing_blank_line =& $matches[5]; + + if ($leading_line || $tailing_blank_line || + preg_match('/\n{2,}/', $item)) + { + // Replace marker with the appropriate whitespace indentation + $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; + $item = $this->runBlockGamut($this->outdent($item)."\n"); + } else { + // Recursion for sub-lists: + $item = $this->doLists($this->outdent($item)); + $item = $this->formParagraphs($item, false); + } + + return "
  • " . $item . "
  • \n"; + } + + /** + * Process Markdown `
    ` blocks.
    +	 * @param  string $text
    +	 * @return string
    +	 */
    +	protected function doCodeBlocks($text) {
    +		$text = preg_replace_callback('{
    +				(?:\n\n|\A\n?)
    +				(	            # $1 = the code block -- one or more lines, starting with a space/tab
    +				  (?>
    +					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
    +					.*\n+
    +				  )+
    +				)
    +				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
    +			}xm',
    +			array($this, '_doCodeBlocks_callback'), $text);
    +
    +		return $text;
    +	}
    +
    +	/**
    +	 * Code block parsing callback
    +	 * @param  array $matches
    +	 * @return string
    +	 */
    +	protected function _doCodeBlocks_callback($matches) {
    +		$codeblock = $matches[1];
    +
    +		$codeblock = $this->outdent($codeblock);
    +		if (is_callable($this->code_block_content_func)) {
    +			$codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
    +		} else {
    +			$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    +		}
    +
    +		# trim leading newlines and trailing newlines
    +		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
    +
    +		$codeblock = "
    $codeblock\n
    "; + return "\n\n" . $this->hashBlock($codeblock) . "\n\n"; + } + + /** + * Create a code span markup for $code. Called from handleSpanToken. + * @param string $code + * @return string + */ + protected function makeCodeSpan($code) { + if (is_callable($this->code_span_content_func)) { + $code = call_user_func($this->code_span_content_func, $code); + } else { + $code = htmlspecialchars(trim($code), ENT_NOQUOTES); + } + return $this->hashPart("$code"); + } + + /** + * Define the emphasis operators with their regex matches + * @var array + */ + protected $em_relist = array( + '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(?em_relist as $em => $em_re) { + foreach ($this->strong_relist as $strong => $strong_re) { + // Construct list of allowed token expressions. + $token_relist = array(); + if (isset($this->em_strong_relist["$em$strong"])) { + $token_relist[] = $this->em_strong_relist["$em$strong"]; + } + $token_relist[] = $em_re; + $token_relist[] = $strong_re; + + // Construct master expression from list. + $token_re = '{(' . implode('|', $token_relist) . ')}'; + $this->em_strong_prepared_relist["$em$strong"] = $token_re; + } + } + } + + /** + * Convert Markdown italics (emphasis) and bold (strong) to HTML + * @param string $text + * @return string + */ + protected function doItalicsAndBold($text) { + if ($this->in_emphasis_processing) { + return $text; // avoid reentrency + } + $this->in_emphasis_processing = true; + + $token_stack = array(''); + $text_stack = array(''); + $em = ''; + $strong = ''; + $tree_char_em = false; + + while (1) { + // Get prepared regular expression for seraching emphasis tokens + // in current context. + $token_re = $this->em_strong_prepared_relist["$em$strong"]; + + // Each loop iteration search for the next emphasis token. + // Each token is then passed to handleSpanToken. + $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + $text_stack[0] .= $parts[0]; + $token =& $parts[1]; + $text =& $parts[2]; + + if (empty($token)) { + // Reached end of text span: empty stack without emitting. + // any more emphasis. + while ($token_stack[0]) { + $text_stack[1] .= array_shift($token_stack); + $text_stack[0] .= array_shift($text_stack); + } + break; + } + + $token_len = strlen($token); + if ($tree_char_em) { + // Reached closing marker while inside a three-char emphasis. + if ($token_len == 3) { + // Three-char closing marker, close em and strong. + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $em = ''; + $strong = ''; + } else { + // Other closing marker: close one em or strong and + // change current token state to match the other + $token_stack[0] = str_repeat($token[0], 3-$token_len); + $tag = $token_len == 2 ? "strong" : "em"; + $span = $text_stack[0]; + $span = $this->runSpanGamut($span); + $span = "<$tag>$span"; + $text_stack[0] = $this->hashPart($span); + $$tag = ''; // $$tag stands for $em or $strong + } + $tree_char_em = false; + } else if ($token_len == 3) { + if ($em) { + // Reached closing marker for both em and strong. + // Closing strong marker: + for ($i = 0; $i < 2; ++$i) { + $shifted_token = array_shift($token_stack); + $tag = strlen($shifted_token) == 2 ? "strong" : "em"; + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "<$tag>$span"; + $text_stack[0] .= $this->hashPart($span); + $$tag = ''; // $$tag stands for $em or $strong + } + } else { + // Reached opening three-char emphasis marker. Push on token + // stack; will be handled by the special condition above. + $em = $token[0]; + $strong = "$em$em"; + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $tree_char_em = true; + } + } else if ($token_len == 2) { + if ($strong) { + // Unwind any dangling emphasis marker: + if (strlen($token_stack[0]) == 1) { + $text_stack[1] .= array_shift($token_stack); + $text_stack[0] .= array_shift($text_stack); + $em = ''; + } + // Closing strong marker: + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $strong = ''; + } else { + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $strong = $token; + } + } else { + // Here $token_len == 1 + if ($em) { + if (strlen($token_stack[0]) == 1) { + // Closing emphasis marker: + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $em = ''; + } else { + $text_stack[0] .= $token; + } + } else { + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $em = $token; + } + } + } + $this->in_emphasis_processing = false; + return $text_stack[0]; + } + + /** + * Parse Markdown blockquotes to HTML + * @param string $text + * @return string + */ + protected function doBlockQuotes($text) { + $text = preg_replace_callback('/ + ( # Wrap whole match in $1 + (?> + ^[ ]*>[ ]? # ">" at the start of a line + .+\n # rest of the first line + (.+\n)* # subsequent consecutive lines + \n* # blanks + )+ + ) + /xm', + array($this, '_doBlockQuotes_callback'), $text); + + return $text; + } + + /** + * Blockquote parsing callback + * @param array $matches + * @return string + */ + protected function _doBlockQuotes_callback($matches) { + $bq = $matches[1]; + // trim one level of quoting - trim whitespace-only lines + $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); + $bq = $this->runBlockGamut($bq); // recurse + + $bq = preg_replace('/^/m', " ", $bq); + // These leading spaces cause problem with
     content,
    +		// so we need to fix that:
    +		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', + array($this, '_doBlockQuotes_callback2'), $bq); + + return "\n" . $this->hashBlock("
    \n$bq\n
    ") . "\n\n"; + } + + /** + * Blockquote parsing callback + * @param array $matches + * @return string + */ + protected function _doBlockQuotes_callback2($matches) { + $pre = $matches[1]; + $pre = preg_replace('/^ /m', '', $pre); + return $pre; + } + + /** + * Parse paragraphs + * + * @param string $text String to process in paragraphs + * @param boolean $wrap_in_p Whether paragraphs should be wrapped in

    tags + * @return string + */ + protected function formParagraphs($text, $wrap_in_p = true) { + // Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + // Wrap

    tags and unhashify HTML blocks + foreach ($grafs as $key => $value) { + if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { + // Is a paragraph. + $value = $this->runSpanGamut($value); + if ($wrap_in_p) { + $value = preg_replace('/^([ ]*)/', "

    ", $value); + $value .= "

    "; + } + $grafs[$key] = $this->unhash($value); + } else { + // Is a block. + // Modify elements of @grafs in-place... + $graf = $value; + $block = $this->html_hashes[$graf]; + $graf = $block; +// if (preg_match('{ +// \A +// ( # $1 =
    tag +//
    ]* +// \b +// markdown\s*=\s* ([\'"]) # $2 = attr quote char +// 1 +// \2 +// [^>]* +// > +// ) +// ( # $3 = contents +// .* +// ) +// (
    ) # $4 = closing tag +// \z +// }xs', $block, $matches)) +// { +// list(, $div_open, , $div_content, $div_close) = $matches; +// +// // We can't call Markdown(), because that resets the hash; +// // that initialization code should be pulled into its own sub, though. +// $div_content = $this->hashHTMLBlocks($div_content); +// +// // Run document gamut methods on the content. +// foreach ($this->document_gamut as $method => $priority) { +// $div_content = $this->$method($div_content); +// } +// +// $div_open = preg_replace( +// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open); +// +// $graf = $div_open . "\n" . $div_content . "\n" . $div_close; +// } + $grafs[$key] = $graf; + } + } + + return implode("\n\n", $grafs); + } + + /** + * Encode text for a double-quoted HTML attribute. This function + * is *not* suitable for attributes enclosed in single quotes. + * @param string $text + * @return string + */ + protected function encodeAttribute($text) { + $text = $this->encodeAmpsAndAngles($text); + $text = str_replace('"', '"', $text); + return $text; + } + + /** + * Encode text for a double-quoted HTML attribute containing a URL, + * applying the URL filter if set. Also generates the textual + * representation for the URL (removing mailto: or tel:) storing it in $text. + * This function is *not* suitable for attributes enclosed in single quotes. + * + * @param string $url + * @param string $text Passed by reference + * @return string URL + */ + protected function encodeURLAttribute($url, &$text = null) { + if (is_callable($this->url_filter_func)) { + $url = call_user_func($this->url_filter_func, $url); + } + + if (preg_match('{^mailto:}i', $url)) { + $url = $this->encodeEntityObfuscatedAttribute($url, $text, 7); + } else if (preg_match('{^tel:}i', $url)) { + $url = $this->encodeAttribute($url); + $text = substr($url, 4); + } else { + $url = $this->encodeAttribute($url); + $text = $url; + } + + return $url; + } + + /** + * Smart processing for ampersands and angle brackets that need to + * be encoded. Valid character entities are left alone unless the + * no-entities mode is set. + * @param string $text + * @return string + */ + protected function encodeAmpsAndAngles($text) { + if ($this->no_entities) { + $text = str_replace('&', '&', $text); + } else { + // Ampersand-encoding based entirely on Nat Irons's Amputator + // MT plugin: + $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', + '&', $text); + } + // Encode remaining <'s + $text = str_replace('<', '<', $text); + + return $text; + } + + /** + * Parse Markdown automatic links to anchor HTML tags + * @param string $text + * @return string + */ + protected function doAutoLinks($text) { + $text = preg_replace_callback('{<((https?|ftp|dict|tel):[^\'">\s]+)>}i', + array($this, '_doAutoLinks_url_callback'), $text); + + // Email addresses: + $text = preg_replace_callback('{ + < + (?:mailto:)? + ( + (?: + [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+ + | + ".*?" + ) + \@ + (?: + [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+ + | + \[[\d.a-fA-F:]+\] # IPv4 & IPv6 + ) + ) + > + }xi', + array($this, '_doAutoLinks_email_callback'), $text); + + return $text; + } + + /** + * Parse URL callback + * @param array $matches + * @return string + */ + protected function _doAutoLinks_url_callback($matches) { + $url = $this->encodeURLAttribute($matches[1], $text); + $link = "$text"; + return $this->hashPart($link); + } + + /** + * Parse email address callback + * @param array $matches + * @return string + */ + protected function _doAutoLinks_email_callback($matches) { + $addr = $matches[1]; + $url = $this->encodeURLAttribute("mailto:$addr", $text); + $link = "$text"; + return $this->hashPart($link); + } + + /** + * Input: some text to obfuscate, e.g. "mailto:foo@example.com" + * + * Output: the same text but with most characters encoded as either a + * decimal or hex entity, in the hopes of foiling most address + * harvesting spam bots. E.g.: + * + * mailto:foo + * @example.co + * m + * + * Note: the additional output $tail is assigned the same value as the + * ouput, minus the number of characters specified by $head_length. + * + * Based by a filter by Matthew Wickline, posted to BBEdit-Talk. + * With some optimizations by Milian Wolff. Forced encoding of HTML + * attribute special characters by Allan Odgaard. + * + * @param string $text + * @param string $tail Passed by reference + * @param integer $head_length + * @return string + */ + protected function encodeEntityObfuscatedAttribute($text, &$tail = null, $head_length = 0) { + if ($text == "") { + return $tail = ""; + } + + $chars = preg_split('/(? $char) { + $ord = ord($char); + // Ignore non-ascii chars. + if ($ord < 128) { + $r = ($seed * (1 + $key)) % 100; // Pseudo-random function. + // roughly 10% raw, 45% hex, 45% dec + // '@' *must* be encoded. I insist. + // '"' and '>' have to be encoded inside the attribute + if ($r > 90 && strpos('@"&>', $char) === false) { + /* do nothing */ + } else if ($r < 45) { + $chars[$key] = '&#x'.dechex($ord).';'; + } else { + $chars[$key] = '&#'.$ord.';'; + } + } + } + + $text = implode('', $chars); + $tail = $head_length ? implode('', array_slice($chars, $head_length)) : $text; + + return $text; + } + + /** + * Take the string $str and parse it into tokens, hashing embeded HTML, + * escaped characters and handling code spans. + * @param string $str + * @return string + */ + protected function parseSpan($str) { + $output = ''; + + $span_re = '{ + ( + \\\\'.$this->escape_chars_re.' + | + (?no_markup ? '' : ' + | + # comment + | + <\?.*?\?> | <%.*?%> # processing instruction + | + <[!$]?[-a-zA-Z0-9:_]+ # regular tags + (?> + \s + (?>[^"\'>]+|"[^"]*"|\'[^\']*\')* + )? + > + | + <[-a-zA-Z0-9:_]+\s*/> # xml-style empty tag + | + # closing tag + ').' + ) + }xs'; + + while (1) { + // Each loop iteration seach for either the next tag, the next + // openning code span marker, or the next escaped character. + // Each token is then passed to handleSpanToken. + $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); + + // Create token from text preceding tag. + if ($parts[0] != "") { + $output .= $parts[0]; + } + + // Check if we reach the end. + if (isset($parts[1])) { + $output .= $this->handleSpanToken($parts[1], $parts[2]); + $str = $parts[2]; + } else { + break; + } + } + + return $output; + } + + /** + * Handle $token provided by parseSpan by determining its nature and + * returning the corresponding value that should replace it. + * @param string $token + * @param string $str Passed by reference + * @return string + */ + protected function handleSpanToken($token, &$str) { + switch ($token[0]) { + case "\\": + return $this->hashPart("&#". ord($token[1]). ";"); + case "`": + // Search for end marker in remaining text. + if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', + $str, $matches)) + { + $str = $matches[2]; + $codespan = $this->makeCodeSpan($matches[1]); + return $this->hashPart($codespan); + } + return $token; // Return as text since no ending marker found. + default: + return $this->hashPart($token); + } + } + + /** + * Remove one level of line-leading tabs or spaces + * @param string $text + * @return string + */ + protected function outdent($text) { + return preg_replace('/^(\t|[ ]{1,' . $this->tab_width . '})/m', '', $text); + } + + + /** + * String length function for detab. `_initDetab` will create a function to + * handle UTF-8 if the default function does not exist. + * @var string + */ + protected $utf8_strlen = 'mb_strlen'; + + /** + * Replace tabs with the appropriate amount of spaces. + * + * For each line we separate the line in blocks delemited by tab characters. + * Then we reconstruct every line by adding the appropriate number of space + * between each blocks. + * + * @param string $text + * @return string + */ + protected function detab($text) { + $text = preg_replace_callback('/^.*\t.*$/m', + array($this, '_detab_callback'), $text); + + return $text; + } + + /** + * Replace tabs callback + * @param string $matches + * @return string + */ + protected function _detab_callback($matches) { + $line = $matches[0]; + $strlen = $this->utf8_strlen; // strlen function for UTF-8. + + // Split in blocks. + $blocks = explode("\t", $line); + // Add each blocks to the line. + $line = $blocks[0]; + unset($blocks[0]); // Do not add first block twice. + foreach ($blocks as $block) { + // Calculate amount of space, insert spaces, insert block. + $amount = $this->tab_width - + $strlen($line, 'UTF-8') % $this->tab_width; + $line .= str_repeat(" ", $amount) . $block; + } + return $line; + } + + /** + * Check for the availability of the function in the `utf8_strlen` property + * (initially `mb_strlen`). If the function is not available, create a + * function that will loosely count the number of UTF-8 characters with a + * regular expression. + * @return void + */ + protected function _initDetab() { + + if (function_exists($this->utf8_strlen)) { + return; + } + + $this->utf8_strlen = function($text) { + return preg_match_all('/[\x00-\xBF]|[\xC0-\xFF][\x80-\xBF]*/', $text, $m); + }; + } + + /** + * Swap back in all the tags hashed by _HashHTMLBlocks. + * @param string $text + * @return string + */ + protected function unhash($text) { + return preg_replace_callback('/(.)\x1A[0-9]+\1/', + array($this, '_unhash_callback'), $text); + } + + /** + * Unhashing callback + * @param array $matches + * @return string + */ + protected function _unhash_callback($matches) { + return $this->html_hashes[$matches[0]]; + } +} diff --git a/md/MarkdownExtra.inc.php b/md/MarkdownExtra.inc.php new file mode 100755 index 0000000..d09bd7a --- /dev/null +++ b/md/MarkdownExtra.inc.php @@ -0,0 +1,11 @@ + + * @copyright 2004-2019 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + +namespace md; + +/** + * Markdown Extra Parser Class + */ +class MarkdownExtra extends \md\Markdown { + /** + * Configuration variables + */ + + /** + * Prefix for footnote ids. + * @var string + */ + public $fn_id_prefix = ""; + + /** + * Optional title attribute for footnote links. + * @var string + */ + public $fn_link_title = ""; + + /** + * Optional class attribute for footnote links and backlinks. + * @var string + */ + public $fn_link_class = "footnote-ref"; + public $fn_backlink_class = "footnote-backref"; + + /** + * Content to be displayed within footnote backlinks. The default is '↩'; + * the U+FE0E on the end is a Unicode variant selector used to prevent iOS + * from displaying the arrow character as an emoji. + * Optionally use '^^' and '%%' to refer to the footnote number and + * reference number respectively. {@see parseFootnotePlaceholders()} + * @var string + */ + public $fn_backlink_html = '↩︎'; + + /** + * Optional title and aria-label attributes for footnote backlinks for + * added accessibility (to ensure backlink uniqueness). + * Use '^^' and '%%' to refer to the footnote number and reference number + * respectively. {@see parseFootnotePlaceholders()} + * @var string + */ + public $fn_backlink_title = ""; + public $fn_backlink_label = ""; + + /** + * Class name for table cell alignment (%% replaced left/center/right) + * For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' + * If empty, the align attribute is used instead of a class name. + * @var string + */ + public $table_align_class_tmpl = ''; + + /** + * Optional class prefix for fenced code block. + * @var string + */ + public $code_class_prefix = ""; + + /** + * Class attribute for code blocks goes on the `code` tag; + * setting this to true will put attributes on the `pre` tag instead. + * @var boolean + */ + public $code_attr_on_pre = false; + + /** + * Predefined abbreviations. + * @var array + */ + public $predef_abbr = array(); + + /** + * Only convert atx-style headers if there's a space between the header and # + * @var boolean + */ + public $hashtag_protection = false; + + /** + * Determines whether footnotes should be appended to the end of the document. + * If true, footnote html can be retrieved from $this->footnotes_assembled. + * @var boolean + */ + public $omit_footnotes = false; + + + /** + * After parsing, the HTML for the list of footnotes appears here. + * This is available only if $omit_footnotes == true. + * + * Note: when placing the content of `footnotes_assembled` on the page, + * consider adding the attribute `role="doc-endnotes"` to the `div` or + * `section` that will enclose the list of footnotes so they are + * reachable to accessibility tools the same way they would be with the + * default HTML output. + * @var null|string + */ + public $footnotes_assembled = null; + + /** + * Parser implementation + */ + + /** + * Constructor function. Initialize the parser object. + * @return void + */ + public function __construct() { + // Add extra escapable characters before parent constructor + // initialize the table. + $this->escape_chars .= ':|'; + + // Insert extra document, block, and span transformations. + // Parent constructor will do the sorting. + $this->document_gamut += array( + "doFencedCodeBlocks" => 5, + "stripFootnotes" => 15, + "stripAbbreviations" => 25, + "appendFootnotes" => 50, + ); + $this->block_gamut += array( + "doFencedCodeBlocks" => 5, + "doTables" => 15, + "doDefLists" => 45, + ); + $this->span_gamut += array( + "doFootnotes" => 5, + "doAbbreviations" => 70, + ); + + $this->enhanced_ordered_list = true; + parent::__construct(); + } + + + /** + * Extra variables used during extra transformations. + * @var array + */ + protected $footnotes = array(); + protected $footnotes_ordered = array(); + protected $footnotes_ref_count = array(); + protected $footnotes_numbers = array(); + protected $abbr_desciptions = array(); + /** @var string */ + protected $abbr_word_re = ''; + + /** + * Give the current footnote number. + * @var integer + */ + protected $footnote_counter = 1; + + /** + * Ref attribute for links + * @var array + */ + protected $ref_attr = array(); + + /** + * Setting up Extra-specific variables. + */ + protected function setup() { + parent::setup(); + + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->footnotes_ref_count = array(); + $this->footnotes_numbers = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + $this->footnote_counter = 1; + $this->footnotes_assembled = null; + + foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { + if ($this->abbr_word_re) + $this->abbr_word_re .= '|'; + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + } + } + + /** + * Clearing Extra-specific variables. + */ + protected function teardown() { + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->footnotes_ref_count = array(); + $this->footnotes_numbers = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + + if ( ! $this->omit_footnotes ) + $this->footnotes_assembled = null; + + parent::teardown(); + } + + + /** + * Extra attribute parser + */ + + /** + * Expression to use to catch attributes (includes the braces) + * @var string + */ + protected $id_class_attr_catch_re = '\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}'; + + /** + * Expression to use when parsing in a context when no capture is desired + * @var string + */ + protected $id_class_attr_nocatch_re = '\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}'; + + /** + * Parse attributes caught by the $this->id_class_attr_catch_re expression + * and return the HTML-formatted list of attributes. + * + * Currently supported attributes are .class and #id. + * + * In addition, this method also supports supplying a default Id value, + * which will be used to populate the id attribute in case it was not + * overridden. + * @param string $tag_name + * @param string $attr + * @param mixed $defaultIdValue + * @param array $classes + * @return string + */ + protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) { + if (empty($attr) && !$defaultIdValue && empty($classes)) { + return ""; + } + + // Split on components + preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches); + $elements = $matches[0]; + + // Handle classes and IDs (only first ID taken into account) + $attributes = array(); + $id = false; + foreach ($elements as $element) { + if ($element[0] === '.') { + $classes[] = substr($element, 1); + } else if ($element[0] === '#') { + if ($id === false) $id = substr($element, 1); + } else if (strpos($element, '=') > 0) { + $parts = explode('=', $element, 2); + $attributes[] = $parts[0] . '="' . $parts[1] . '"'; + } + } + + if ($id === false || $id === '') { + $id = $defaultIdValue; + } + + // Compose attributes as string + $attr_str = ""; + if (!empty($id)) { + $attr_str .= ' id="'.$this->encodeAttribute($id) .'"'; + } + if (!empty($classes)) { + $attr_str .= ' class="'. implode(" ", $classes) . '"'; + } + if (!$this->no_markup && !empty($attributes)) { + $attr_str .= ' '.implode(" ", $attributes); + } + return $attr_str; + } + + /** + * Strips link definitions from text, stores the URLs and titles in + * hash references. + * @param string $text + * @return string + */ + protected function stripLinkDefinitions($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: ^[id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 + [ ]* + \n? # maybe *one* newline + [ ]* + (?: + <(.+?)> # url = $2 + | + (\S+?) # url = $3 + ) + [ ]* + \n? # maybe one newline + [ ]* + (?: + (?<=\s) # lookbehind for whitespace + ["(] + (.*?) # title = $4 + [")] + [ ]* + )? # title is optional + (?:[ ]* '.$this->id_class_attr_catch_re.' )? # $5 = extra id & class attr + (?:\n+|\Z) + }xm', + array($this, '_stripLinkDefinitions_callback'), + $text); + return $text; + } + + /** + * Strip link definition callback + * @param array $matches + * @return string + */ + protected function _stripLinkDefinitions_callback($matches) { + $link_id = strtolower($matches[1]); + $url = $matches[2] == '' ? $matches[3] : $matches[2]; + $this->urls[$link_id] = $url; + $this->titles[$link_id] =& $matches[4]; + $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]); + return ''; // String that will replace the block + } + + + /** + * HTML block parser + */ + + /** + * Tags that are always treated as block tags + * @var string + */ + protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure|details|summary'; + + /** + * Tags treated as block tags only if the opening tag is alone on its line + * @var string + */ + protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video'; + + /** + * Tags where markdown="1" default to span mode: + * @var string + */ + protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; + + /** + * Tags which must not have their contents modified, no matter where + * they appear + * @var string + */ + protected $clean_tags_re = 'script|style|math|svg'; + + /** + * Tags that do not need to be closed. + * @var string + */ + protected $auto_close_tags_re = 'hr|img|param|source|track'; + + /** + * Hashify HTML Blocks and "clean tags". + * + * We only want to do this for block-level HTML tags, such as headers, + * lists, and tables. That's because we still want to wrap

    s around + * "paragraphs" that are wrapped in non-block-level tags, such as anchors, + * phrase emphasis, and spans. The list of tags we're looking for is + * hard-coded. + * + * This works by calling _HashHTMLBlocks_InMarkdown, which then calls + * _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" + * attribute is found within a tag, _HashHTMLBlocks_InHTML calls back + * _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. + * These two functions are calling each other. It's recursive! + * @param string $text + * @return string + */ + protected function hashHTMLBlocks($text) { + if ($this->no_markup) { + return $text; + } + + // Call the HTML-in-Markdown hasher. + list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); + + return $text; + } + + /** + * Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. + * + * * $indent is the number of space to be ignored when checking for code + * blocks. This is important because if we don't take the indent into + * account, something like this (which looks right) won't work as expected: + * + *

    + *
    + * Hello World. <-- Is this a Markdown code block or text? + *
    <-- Is this a Markdown code block or a real tag? + *
    + * + * If you don't like this, just don't indent the tag on which + * you apply the markdown="1" attribute. + * + * * If $enclosing_tag_re is not empty, stops at the first unmatched closing + * tag with that name. Nested tags supported. + * + * * If $span is true, text inside must treated as span. So any double + * newline will be replaced by a single newline so that it does not create + * paragraphs. + * + * Returns an array of that form: ( processed text , remaining text ) + * + * @param string $text + * @param integer $indent + * @param string $enclosing_tag_re + * @param boolean $span + * @return array + */ + protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0, + $enclosing_tag_re = '', $span = false) + { + + if ($text === '') return array('', ''); + + // Regex to check for the presense of newlines around a block tag. + $newline_before_re = '/(?:^\n?|\n\n)*$/'; + $newline_after_re = + '{ + ^ # Start of text following the tag. + (?>[ ]*)? # Optional comment. + [ ]*\n # Must be followed by newline. + }xs'; + + // Regex to match any tag. + $block_tag_re = + '{ + ( # $2: Capture whole tag. + # Tag name. + ' . $this->block_tags_re . ' | + ' . $this->context_block_tags_re . ' | + ' . $this->clean_tags_re . ' | + (?!\s)'.$enclosing_tag_re . ' + ) + (?: + (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name. + (?> + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + ' . ( !$span ? ' # If not in span. + | + # Indented code block + (?: ^[ ]*\n | ^ | \n[ ]*\n ) + [ ]{' . ($indent + 4) . '}[^\n]* \n + (?> + (?: [ ]{' . ($indent + 4) . '}[^\n]* | [ ]* ) \n + )* + | + # Fenced code block marker + (?<= ^ | \n ) + [ ]{0,' . ($indent + 3) . '}(?:~{3,}|`{3,}) + [ ]* + (?: \.?[-_:a-zA-Z0-9]+ )? # standalone class name + [ ]* + (?: ' . $this->id_class_attr_nocatch_re . ' )? # extra attributes + [ ]* + (?= \n ) + ' : '' ) . ' # End (if not is span). + | + # Code span marker + # Note, this regex needs to go after backtick fenced + # code blocks but it should also be kept outside of the + # "if not in span" condition adding backticks to the parser + `+ + ) + }xs'; + + + $depth = 0; // Current depth inside the tag tree. + $parsed = ""; // Parsed text that will be returned. + + // Loop through every tag until we find the closing tag of the parent + // or loop until reaching the end of text if no parent tag specified. + do { + // Split the text using the first $tag_match pattern found. + // Text before pattern will be first in the array, text after + // pattern will be at the end, and between will be any catches made + // by the pattern. + $parts = preg_split($block_tag_re, $text, 2, + PREG_SPLIT_DELIM_CAPTURE); + + // If in Markdown span mode, add a empty-string span-level hash + // after each newline to prevent triggering any block element. + if ($span) { + $void = $this->hashPart("", ':'); + $newline = "\n$void"; + $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; + } + + $parsed .= $parts[0]; // Text before current tag. + + // If end of $text has been reached. Stop loop. + if (count($parts) < 3) { + $text = ""; + break; + } + + $tag = $parts[1]; // Tag to handle. + $text = $parts[2]; // Remaining text after current tag. + + // Check for: Fenced code block marker. + // Note: need to recheck the whole tag to disambiguate backtick + // fences from code spans + if (preg_match('{^\n?([ ]{0,' . ($indent + 3) . '})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+)?[ ]*(?:' . $this->id_class_attr_nocatch_re . ')?[ ]*\n?$}', $tag, $capture)) { + // Fenced code block marker: find matching end marker. + $fence_indent = strlen($capture[1]); // use captured indent in re + $fence_re = $capture[2]; // use captured fence in re + if (preg_match('{^(?>.*\n)*?[ ]{' . ($fence_indent) . '}' . $fence_re . '[ ]*(?:\n|$)}', $text, + $matches)) + { + // End marker found: pass text unchanged until marker. + $parsed .= $tag . $matches[0]; + $text = substr($text, strlen($matches[0])); + } + else { + // No end marker: just skip it. + $parsed .= $tag; + } + } + // Check for: Indented code block. + else if ($tag[0] === "\n" || $tag[0] === " ") { + // Indented code block: pass it unchanged, will be handled + // later. + $parsed .= $tag; + } + // Check for: Code span marker + // Note: need to check this after backtick fenced code blocks + else if ($tag[0] === "`") { + // Find corresponding end marker. + $tag_re = preg_quote($tag); + if (preg_match('{^(?>.+?|\n(?!\n))*?(?block_tags_re . ')\b}', $tag) || + ( preg_match('{^<(?:' . $this->context_block_tags_re . ')\b}', $tag) && + preg_match($newline_before_re, $parsed) && + preg_match($newline_after_re, $text) ) + ) + { + // Need to parse tag and following text using the HTML parser. + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); + + // Make sure it stays outside of any paragraph by adding newlines. + $parsed .= "\n\n$block_text\n\n"; + } + // Check for: Clean tag (like script, math) + // HTML Comments, processing instructions. + else if (preg_match('{^<(?:' . $this->clean_tags_re . ')\b}', $tag) || + $tag[1] === '!' || $tag[1] === '?') + { + // Need to parse tag and following text using the HTML parser. + // (don't check for markdown attribute) + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); + + $parsed .= $block_text; + } + // Check for: Tag with same name as enclosing tag. + else if ($enclosing_tag_re !== '' && + // Same name as enclosing tag. + preg_match('{^= 0); + + return array($parsed, $text); + } + + /** + * Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. + * + * * Calls $hash_method to convert any blocks. + * * Stops when the first opening tag closes. + * * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. + * (it is not inside clean tags) + * + * Returns an array of that form: ( processed text , remaining text ) + * @param string $text + * @param string $hash_method + * @param bool $md_attr Handle `markdown="1"` attribute + * @return array + */ + protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { + if ($text === '') return array('', ''); + + // Regex to match `markdown` attribute inside of a tag. + $markdown_attr_re = ' + { + \s* # Eat whitespace before the `markdown` attribute + markdown + \s*=\s* + (?> + (["\']) # $1: quote delimiter + (.*?) # $2: attribute value + \1 # matching delimiter + | + ([^\s>]*) # $3: unquoted attribute value + ) + () # $4: make $3 always defined (avoid warnings) + }xs'; + + // Regex to match any tag. + $tag_re = '{ + ( # $2: Capture whole tag. + + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + ) + }xs'; + + $original_text = $text; // Save original text in case of faliure. + + $depth = 0; // Current depth inside the tag tree. + $block_text = ""; // Temporary text holder for current text. + $parsed = ""; // Parsed text that will be returned. + $base_tag_name_re = ''; + + // Get the name of the starting tag. + // (This pattern makes $base_tag_name_re safe without quoting.) + if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) + $base_tag_name_re = $matches[1]; + + // Loop through every tag until we find the corresponding closing tag. + do { + // Split the text using the first $tag_match pattern found. + // Text before pattern will be first in the array, text after + // pattern will be at the end, and between will be any catches made + // by the pattern. + $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + + if (count($parts) < 3) { + // End of $text reached with unbalenced tag(s). + // In that case, we return original text unchanged and pass the + // first character as filtered to prevent an infinite loop in the + // parent function. + return array($original_text[0], substr($original_text, 1)); + } + + $block_text .= $parts[0]; // Text before current tag. + $tag = $parts[1]; // Tag to handle. + $text = $parts[2]; // Remaining text after current tag. + + // Check for: Auto-close tag (like
    ) + // Comments and Processing Instructions. + if (preg_match('{^auto_close_tags_re . ')\b}', $tag) || + $tag[1] === '!' || $tag[1] === '?') + { + // Just add the tag to the block as if it was text. + $block_text .= $tag; + } + else { + // Increase/decrease nested tag count. Only do so if + // the tag's name match base tag's. + if (preg_match('{^contain_span_tags_re . ')\b}', $tag)); + + // Calculate indent before tag. + if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { + $strlen = $this->utf8_strlen; + $indent = $strlen($matches[1], 'UTF-8'); + } else { + $indent = 0; + } + + // End preceding block with this tag. + $block_text .= $tag; + $parsed .= $this->$hash_method($block_text); + + // Get enclosing tag name for the ParseMarkdown function. + // (This pattern makes $tag_name_re safe without quoting.) + preg_match('/^<([\w:$]*)\b/', $tag, $matches); + $tag_name_re = $matches[1]; + + // Parse the content using the HTML-in-Markdown parser. + list ($block_text, $text) + = $this->_hashHTMLBlocks_inMarkdown($text, $indent, + $tag_name_re, $span_mode); + + // Outdent markdown text. + if ($indent > 0) { + $block_text = preg_replace("/^[ ]{1,$indent}/m", "", + $block_text); + } + + // Append tag content to parsed text. + if (!$span_mode) { + $parsed .= "\n\n$block_text\n\n"; + } else { + $parsed .= (string) $block_text; + } + + // Start over with a new block. + $block_text = ""; + } + else $block_text .= $tag; + } + + } while ($depth > 0); + + // Hash last block text that wasn't processed inside the loop. + $parsed .= $this->$hash_method($block_text); + + return array($parsed, $text); + } + + /** + * Called whenever a tag must be hashed when a function inserts a "clean" tag + * in $text, it passes through this function and is automaticaly escaped, + * blocking invalid nested overlap. + * @param string $text + * @return string + */ + protected function hashClean($text) { + return $this->hashPart($text, 'C'); + } + + /** + * Turn Markdown link shortcuts into XHTML tags. + * @param string $text + * @return string + */ + protected function doAnchors($text) { + if ($this->in_anchor) { + return $text; + } + $this->in_anchor = true; + + // First, handle reference-style links: [link text] [id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + (' . $this->nested_brackets_re . ') # link text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + // Next, inline-style links: [link text](url "optional title") + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + (' . $this->nested_brackets_re . ') # link text = $2 + \] + \( # literal paren + [ \n]* + (?: + <(.+?)> # href = $3 + | + (' . $this->nested_url_parenthesis_re . ') # href = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # Title = $7 + \6 # matching quote + [ \n]* # ignore any spaces/tabs between closing quote and ) + )? # title is optional + \) + (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes + ) + }xs', + array($this, '_doAnchors_inline_callback'), $text); + + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link text][1] + // or [link text](/foo) + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ([^\[\]]+) # link text = $2; can\'t contain [ or ] + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + $this->in_anchor = false; + return $text; + } + + /** + * Callback for reference anchors + * @param array $matches + * @return string + */ + protected function _doAnchors_reference_callback($matches) { + $whole_match = $matches[1]; + $link_text = $matches[2]; + $link_id =& $matches[3]; + + if ($link_id == "") { + // for shortcut links like [this][] or [this]. + $link_id = $link_text; + } + + // lower-case and turn embedded newlines into spaces + $link_id = strtolower($link_id); + $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); + + if (isset($this->urls[$link_id])) { + $url = $this->urls[$link_id]; + $url = $this->encodeURLAttribute($url); + + $result = "titles[$link_id] ) ) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + if (isset($this->ref_attr[$link_id])) + $result .= $this->ref_attr[$link_id]; + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + $result = $this->hashPart($result); + } + else { + $result = $whole_match; + } + return $result; + } + + /** + * Callback for inline anchors + * @param array $matches + * @return string + */ + protected function _doAnchors_inline_callback($matches) { + $link_text = $this->runSpanGamut($matches[2]); + $url = $matches[3] === '' ? $matches[4] : $matches[3]; + $title_quote =& $matches[6]; + $title =& $matches[7]; + $attr = $this->doExtraAttributes("a", $dummy =& $matches[8]); + + // if the URL was of the form it got caught by the HTML + // tag parser and hashed. Need to reverse the process before using the URL. + $unhashed = $this->unhash($url); + if ($unhashed !== $url) + $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); + + $url = $this->encodeURLAttribute($url); + + $result = "encodeAttribute($title); + $result .= " title=\"$title\""; + } + $result .= $attr; + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + + return $this->hashPart($result); + } + + /** + * Turn Markdown image shortcuts into tags. + * @param string $text + * @return string + */ + protected function doImages($text) { + // First, handle reference-style labeled images: ![alt text][id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + (' . $this->nested_brackets_re . ') # alt text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + + ) + }xs', + array($this, '_doImages_reference_callback'), $text); + + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + (' . $this->nested_brackets_re . ') # alt text = $2 + \] + \s? # One optional whitespace character + \( # literal paren + [ \n]* + (?: + <(\S*)> # src url = $3 + | + (' . $this->nested_url_parenthesis_re . ') # src url = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # title = $7 + \6 # matching quote + [ \n]* + )? # title is optional + \) + (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes + ) + }xs', + array($this, '_doImages_inline_callback'), $text); + + return $text; + } + + /** + * Callback for referenced images + * @param array $matches + * @return string + */ + protected function _doImages_reference_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $link_id = strtolower($matches[3]); + + if ($link_id === "") { + $link_id = strtolower($alt_text); // for shortcut links like ![this][]. + } + + $alt_text = $this->encodeAttribute($alt_text); + if (isset($this->urls[$link_id])) { + $url = $this->encodeURLAttribute($this->urls[$link_id]); + $result = "\"$alt_text\"";titles[$link_id])) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + if (isset($this->ref_attr[$link_id])) { + $result .= $this->ref_attr[$link_id]; + } + $result .= $this->empty_element_suffix; + $result = $this->hashPart($result); + } + else { + // If there's no such link ID, leave intact: + $result = $whole_match; + } + + return $result; + } + + /** + * Callback for inline images + * @param array $matches + * @return string + */ + protected function _doImages_inline_callback($matches) { + $alt_text = $matches[2]; + $url = $matches[3] === '' ? $matches[4] : $matches[3]; + $title_quote =& $matches[6]; + $title =& $matches[7]; + $attr = $this->doExtraAttributes("img", $dummy =& $matches[8]); + + $alt_text = $this->encodeAttribute($alt_text); + $url = $this->encodeURLAttribute($url); + $result = "\"$alt_text\"";encodeAttribute($title); + $result .= " title=\"$title\""; // $title already quoted + } + $result .= $attr; + $result .= $this->empty_element_suffix; + + return $this->hashPart($result); + } + + /** + * Process markdown headers. Redefined to add ID and class attribute support. + * @param string $text + * @return string + */ + protected function doHeaders($text) { + // Setext-style headers: + // Header 1 {#header1} + // ======== + // + // Header 2 {#header2 .class1 .class2} + // -------- + // + $text = preg_replace_callback( + '{ + (^.+?) # $1: Header text + (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes + [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer + }mx', + array($this, '_doHeaders_callback_setext'), $text); + + // atx-style headers: + // # Header 1 {#header1} + // ## Header 2 {#header2} + // ## Header 2 with closing hashes ## {#header3.class1.class2} + // ... + // ###### Header 6 {.class2} + // + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]'.($this->hashtag_protection ? '+' : '*').' + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes + [ ]* + \n+ + }xm', + array($this, '_doHeaders_callback_atx'), $text); + + return $text; + } + + /** + * Callback for setext headers + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_setext($matches) { + if ($matches[3] === '-' && preg_match('{^- }', $matches[1])) { + return $matches[0]; + } + + $level = $matches[3][0] === '=' ? 1 : 2; + + $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[1]) : null; + + $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[2], $defaultId); + $block = "" . $this->runSpanGamut($matches[1]) . ""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * Callback for atx headers + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_atx($matches) { + $level = strlen($matches[1]); + + $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[2]) : null; + $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[3], $defaultId); + $block = "" . $this->runSpanGamut($matches[2]) . ""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * Form HTML tables. + * @param string $text + * @return string + */ + protected function doTables($text) { + $less_than_tab = $this->tab_width - 1; + // Find tables with leading pipe. + // + // | Header 1 | Header 2 + // | -------- | -------- + // | Cell 1 | Cell 2 + // | Cell 3 | Cell 4 + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + [|] # Optional leading pipe (present) + (.+) \n # $1: Header row (at least one pipe) + + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + [ ]* # Allowed whitespace. + [|] .* \n # Row content. + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array($this, '_doTable_leadingPipe_callback'), $text); + + // Find tables without leading pipe. + // + // Header 1 | Header 2 + // -------- | -------- + // Cell 1 | Cell 2 + // Cell 3 | Cell 4 + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + (\S.*[|].*) \n # $1: Header row (at least one pipe) + + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + .* [|] .* \n # Row content + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array($this, '_DoTable_callback'), $text); + + return $text; + } + + /** + * Callback for removing the leading pipe for each row + * @param array $matches + * @return string + */ + protected function _doTable_leadingPipe_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + $content = preg_replace('/^ *[|]/m', '', $content); + + return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); + } + + /** + * Make the align attribute in a table + * @param string $alignname + * @return string + */ + protected function _doTable_makeAlignAttr($alignname) { + if (empty($this->table_align_class_tmpl)) { + return " align=\"$alignname\""; + } + + $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl); + return " class=\"$classname\""; + } + + /** + * Calback for processing tables + * @param array $matches + * @return string + */ + protected function _doTable_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + // Remove any tailing pipes for each line. + $head = preg_replace('/[|] *$/m', '', $head); + $underline = preg_replace('/[|] *$/m', '', $underline); + $content = preg_replace('/[|] *$/m', '', $content); + + // Reading alignement from header underline. + $separators = preg_split('/ *[|] */', $underline); + foreach ($separators as $n => $s) { + if (preg_match('/^ *-+: *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('right'); + else if (preg_match('/^ *:-+: *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('center'); + else if (preg_match('/^ *:-+ *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('left'); + else + $attr[$n] = ''; + } + + // Parsing span elements, including code spans, character escapes, + // and inline HTML tags, so that pipes inside those gets ignored. + $head = $this->parseSpan($head); + $headers = preg_split('/ *[|] */', $head); + $col_count = count($headers); + $attr = array_pad($attr, $col_count, ''); + + // Write column headers. + $text = "\n"; + $text .= "\n"; + $text .= "\n"; + foreach ($headers as $n => $header) { + $text .= " " . $this->runSpanGamut(trim($header)) . "\n"; + } + $text .= "\n"; + $text .= "\n"; + + // Split content by row. + $rows = explode("\n", trim($content, "\n")); + + $text .= "\n"; + foreach ($rows as $row) { + // Parsing span elements, including code spans, character escapes, + // and inline HTML tags, so that pipes inside those gets ignored. + $row = $this->parseSpan($row); + + // Split row by cell. + $row_cells = preg_split('/ *[|] */', $row, $col_count); + $row_cells = array_pad($row_cells, $col_count, ''); + + $text .= "\n"; + foreach ($row_cells as $n => $cell) { + $text .= " " . $this->runSpanGamut(trim($cell)) . "\n"; + } + $text .= "\n"; + } + $text .= "\n"; + $text .= "
    "; + + return $this->hashBlock($text) . "\n"; + } + + /** + * Form HTML definition lists. + * @param string $text + * @return string + */ + protected function doDefLists($text) { + $less_than_tab = $this->tab_width - 1; + + // Re-usable pattern to match any entire dl list: + $whole_list_re = '(?> + ( # $1 = whole list + ( # $2 + [ ]{0,' . $less_than_tab . '} + ((?>.*\S.*\n)+) # $3 = defined term + \n? + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + (?s:.+?) + ( # $4 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another term + [ ]{0,' . $less_than_tab . '} + (?: \S.*\n )+? # defined term + \n? + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + (?! # Negative lookahead for another definition + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + ) + ) + )'; // mx + + $text = preg_replace_callback('{ + (?>\A\n?|(?<=\n\n)) + ' . $whole_list_re . ' + }mx', + array($this, '_doDefLists_callback'), $text); + + return $text; + } + + /** + * Callback for processing definition lists + * @param array $matches + * @return string + */ + protected function _doDefLists_callback($matches) { + // Re-usable patterns to match list item bullets and number markers: + $list = $matches[1]; + + // Turn double returns into triple returns, so that we can make a + // paragraph for the last item in a list, if necessary: + $result = trim($this->processDefListItems($list)); + $result = "
    \n" . $result . "\n
    "; + return $this->hashBlock($result) . "\n\n"; + } + + /** + * Process the contents of a single definition list, splitting it + * into individual term and definition list items. + * @param string $list_str + * @return string + */ + protected function processDefListItems($list_str) { + + $less_than_tab = $this->tab_width - 1; + + // Trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + // Process definition terms. + $list_str = preg_replace_callback('{ + (?>\A\n?|\n\n+) # leading line + ( # definition terms = $1 + [ ]{0,' . $less_than_tab . '} # leading whitespace + (?!\:[ ]|[ ]) # negative lookahead for a definition + # mark (colon) or more whitespace. + (?> \S.* \n)+? # actual term (not whitespace). + ) + (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed + # with a definition mark. + }xm', + array($this, '_processDefListItems_callback_dt'), $list_str); + + // Process actual definitions. + $list_str = preg_replace_callback('{ + \n(\n+)? # leading line = $1 + ( # marker space = $2 + [ ]{0,' . $less_than_tab . '} # whitespace before colon + \:[ ]+ # definition mark (colon) + ) + ((?s:.+?)) # definition text = $3 + (?= \n+ # stop at next definition mark, + (?: # next term or end of text + [ ]{0,' . $less_than_tab . '} \:[ ] | +
    | \z + ) + ) + }xm', + array($this, '_processDefListItems_callback_dd'), $list_str); + + return $list_str; + } + + /** + * Callback for
    elements in definition lists + * @param array $matches + * @return string + */ + protected function _processDefListItems_callback_dt($matches) { + $terms = explode("\n", trim($matches[1])); + $text = ''; + foreach ($terms as $term) { + $term = $this->runSpanGamut(trim($term)); + $text .= "\n
    " . $term . "
    "; + } + return $text . "\n"; + } + + /** + * Callback for
    elements in definition lists + * @param array $matches + * @return string + */ + protected function _processDefListItems_callback_dd($matches) { + $leading_line = $matches[1]; + $marker_space = $matches[2]; + $def = $matches[3]; + + if ($leading_line || preg_match('/\n{2,}/', $def)) { + // Replace marker with the appropriate whitespace indentation + $def = str_repeat(' ', strlen($marker_space)) . $def; + $def = $this->runBlockGamut($this->outdent($def . "\n\n")); + $def = "\n". $def ."\n"; + } + else { + $def = rtrim($def); + $def = $this->runSpanGamut($this->outdent($def)); + } + + return "\n
    " . $def . "
    \n"; + } + + /** + * Adding the fenced code block syntax to regular Markdown: + * + * ~~~ + * Code block + * ~~~ + * + * @param string $text + * @return string + */ + protected function doFencedCodeBlocks($text) { + + $text = preg_replace_callback('{ + (?:\n|\A) + # 1: Opening marker + ( + (?:~{3,}|`{3,}) # 3 or more tildes/backticks. + ) + [ ]* + (?: + \.?([-_:a-zA-Z0-9]+) # 2: standalone class name + )? + [ ]* + (?: + ' . $this->id_class_attr_catch_re . ' # 3: Extra attributes + )? + [ ]* \n # Whitespace and newline following marker. + + # 4: Content + ( + (?> + (?!\1 [ ]* \n) # Not a closing marker. + .*\n+ + )+ + ) + + # Closing marker. + \1 [ ]* (?= \n ) + }xm', + array($this, '_doFencedCodeBlocks_callback'), $text); + + return $text; + } + + /** + * Callback to process fenced code blocks + * @param array $matches + * @return string + */ + protected function _doFencedCodeBlocks_callback($matches) { + $classname =& $matches[2]; + $attrs =& $matches[3]; + $codeblock = $matches[4]; + + if ($this->code_block_content_func) { + $codeblock = call_user_func($this->code_block_content_func, $codeblock, $classname); + } else { + $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); + } + + $codeblock = preg_replace_callback('/^\n+/', + array($this, '_doFencedCodeBlocks_newlines'), $codeblock); + + $classes = array(); + if ($classname !== "") { + if ($classname[0] === '.') { + $classname = substr($classname, 1); + } + $classes[] = $this->code_class_prefix . $classname; + } + $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes); + $pre_attr_str = $this->code_attr_on_pre ? $attr_str : ''; + $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str; + $codeblock = "$codeblock
    "; + + return "\n\n".$this->hashBlock($codeblock)."\n\n"; + } + + /** + * Replace new lines in fenced code blocks + * @param array $matches + * @return string + */ + protected function _doFencedCodeBlocks_newlines($matches) { + return str_repeat("empty_element_suffix", + strlen($matches[0])); + } + + /** + * Redefining emphasis markers so that emphasis by underscore does not + * work in the middle of a word. + * @var array + */ + protected $em_relist = array( + '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(? tags + * @return string HTML output + */ + protected function formParagraphs($text, $wrap_in_p = true) { + // Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + // Wrap

    tags and unhashify HTML blocks + foreach ($grafs as $key => $value) { + $value = trim($this->runSpanGamut($value)); + + // Check if this should be enclosed in a paragraph. + // Clean tag hashes & block tag hashes are left alone. + $is_p = $wrap_in_p && !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); + + if ($is_p) { + $value = "

    $value

    "; + } + $grafs[$key] = $value; + } + + // Join grafs in one text, then unhash HTML tags. + $text = implode("\n\n", $grafs); + + // Finish by removing any tag hashes still present in $text. + $text = $this->unhash($text); + + return $text; + } + + + /** + * Footnotes - Strips link definitions from text, stores the URLs and + * titles in hash references. + * @param string $text + * @return string + */ + protected function stripFootnotes($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: [^id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,' . $less_than_tab . '}\[\^(.+?)\][ ]?: # note_id = $1 + [ ]* + \n? # maybe *one* newline + ( # text = $2 (no blank lines allowed) + (?: + .+ # actual text + | + \n # newlines but + (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker. + (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed + # by non-indented content + )* + ) + }xm', + array($this, '_stripFootnotes_callback'), + $text); + return $text; + } + + /** + * Callback for stripping footnotes + * @param array $matches + * @return string + */ + protected function _stripFootnotes_callback($matches) { + $note_id = $this->fn_id_prefix . $matches[1]; + $this->footnotes[$note_id] = $this->outdent($matches[2]); + return ''; // String that will replace the block + } + + /** + * Replace footnote references in $text [^id] with a special text-token + * which will be replaced by the actual footnote marker in appendFootnotes. + * @param string $text + * @return string + */ + protected function doFootnotes($text) { + if (!$this->in_anchor) { + $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); + } + return $text; + } + + /** + * Append footnote list to text + * @param string $text + * @return string + */ + protected function appendFootnotes($text) { + $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array($this, '_appendFootnotes_callback'), $text); + + if ( ! empty( $this->footnotes_ordered ) ) { + $this->_doFootnotes(); + if ( ! $this->omit_footnotes ) { + $text .= "\n\n"; + $text .= "
    \n"; + $text .= "empty_element_suffix . "\n"; + $text .= $this->footnotes_assembled; + $text .= "
    "; + } + } + return $text; + } + + + /** + * Generates the HTML for footnotes. Called by appendFootnotes, even if + * footnotes are not being appended. + * @return void + */ + protected function _doFootnotes() { + $attr = array(); + if ($this->fn_backlink_class !== "") { + $class = $this->fn_backlink_class; + $class = $this->encodeAttribute($class); + $attr['class'] = " class=\"$class\""; + } + $attr['role'] = " role=\"doc-backlink\""; + $num = 0; + + $text = "
      \n\n"; + while (!empty($this->footnotes_ordered)) { + $footnote = reset($this->footnotes_ordered); + $note_id = key($this->footnotes_ordered); + unset($this->footnotes_ordered[$note_id]); + $ref_count = $this->footnotes_ref_count[$note_id]; + unset($this->footnotes_ref_count[$note_id]); + unset($this->footnotes[$note_id]); + + $footnote .= "\n"; // Need to append newline before parsing. + $footnote = $this->runBlockGamut("$footnote\n"); + $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array($this, '_appendFootnotes_callback'), $footnote); + + $num++; + $note_id = $this->encodeAttribute($note_id); + + // Prepare backlink, multiple backlinks if multiple references + // Do not create empty backlinks if the html is blank + $backlink = ""; + if (!empty($this->fn_backlink_html)) { + for ($ref_num = 1; $ref_num <= $ref_count; ++$ref_num) { + if (!empty($this->fn_backlink_title)) { + $attr['title'] = ' title="' . $this->encodeAttribute($this->fn_backlink_title) . '"'; + } + if (!empty($this->fn_backlink_label)) { + $attr['label'] = ' aria-label="' . $this->encodeAttribute($this->fn_backlink_label) . '"'; + } + $parsed_attr = $this->parseFootnotePlaceholders( + implode('', $attr), + $num, + $ref_num + ); + $backlink_text = $this->parseFootnotePlaceholders( + $this->fn_backlink_html, + $num, + $ref_num + ); + $ref_count_mark = $ref_num > 1 ? $ref_num : ''; + $backlink .= " $backlink_text"; + } + $backlink = trim($backlink); + } + + // Add backlink to last paragraph; create new paragraph if needed. + if (!empty($backlink)) { + if (preg_match('{

      $}', $footnote)) { + $footnote = substr($footnote, 0, -4) . " $backlink

      "; + } else { + $footnote .= "\n\n

      $backlink

      "; + } + } + + $text .= "
    1. \n"; + $text .= $footnote . "\n"; + $text .= "
    2. \n\n"; + } + $text .= "
    \n"; + + $this->footnotes_assembled = $text; + } + + /** + * Callback for appending footnotes + * @param array $matches + * @return string + */ + protected function _appendFootnotes_callback($matches) { + $node_id = $this->fn_id_prefix . $matches[1]; + + // Create footnote marker only if it has a corresponding footnote *and* + // the footnote hasn't been used by another marker. + if (isset($this->footnotes[$node_id])) { + $num =& $this->footnotes_numbers[$node_id]; + if (!isset($num)) { + // Transfer footnote content to the ordered list and give it its + // number + $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; + $this->footnotes_ref_count[$node_id] = 1; + $num = $this->footnote_counter++; + $ref_count_mark = ''; + } else { + $ref_count_mark = $this->footnotes_ref_count[$node_id] += 1; + } + + $attr = ""; + if ($this->fn_link_class !== "") { + $class = $this->fn_link_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_link_title !== "") { + $title = $this->fn_link_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + } + $attr .= " role=\"doc-noteref\""; + + $attr = str_replace("%%", $num, $attr); + $node_id = $this->encodeAttribute($node_id); + + return + "". + "$num". + ""; + } + + return "[^" . $matches[1] . "]"; + } + + /** + * Build footnote label by evaluating any placeholders. + * - ^^ footnote number + * - %% footnote reference number (Nth reference to footnote number) + * @param string $label + * @param int $footnote_number + * @param int $reference_number + * @return string + */ + protected function parseFootnotePlaceholders($label, $footnote_number, $reference_number) { + return str_replace( + array('^^', '%%'), + array($footnote_number, $reference_number), + $label + ); + } + + + /** + * Abbreviations - strips abbreviations from text, stores titles in hash + * references. + * @param string $text + * @return string + */ + protected function stripAbbreviations($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: [id]*: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,' . $less_than_tab . '}\*\[(.+?)\][ ]?: # abbr_id = $1 + (.*) # text = $2 (no blank lines allowed) + }xm', + array($this, '_stripAbbreviations_callback'), + $text); + return $text; + } + + /** + * Callback for stripping abbreviations + * @param array $matches + * @return string + */ + protected function _stripAbbreviations_callback($matches) { + $abbr_word = $matches[1]; + $abbr_desc = $matches[2]; + if ($this->abbr_word_re) { + $this->abbr_word_re .= '|'; + } + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + return ''; // String that will replace the block + } + + /** + * Find defined abbreviations in text and wrap them in elements. + * @param string $text + * @return string + */ + protected function doAbbreviations($text) { + if ($this->abbr_word_re) { + // cannot use the /x modifier because abbr_word_re may + // contain significant spaces: + $text = preg_replace_callback('{' . + '(?abbr_word_re . ')' . + '(?![\w\x1A])' . + '}', + array($this, '_doAbbreviations_callback'), $text); + } + return $text; + } + + /** + * Callback for processing abbreviations + * @param array $matches + * @return string + */ + protected function _doAbbreviations_callback($matches) { + $abbr = $matches[0]; + if (isset($this->abbr_desciptions[$abbr])) { + $desc = $this->abbr_desciptions[$abbr]; + if (empty($desc)) { + return $this->hashPart("$abbr"); + } + $desc = $this->encodeAttribute($desc); + return $this->hashPart("$abbr"); + } + return $matches[0]; + } +} diff --git a/md/MarkdownInterface.inc.php b/md/MarkdownInterface.inc.php new file mode 100755 index 0000000..c4e9ac7 --- /dev/null +++ b/md/MarkdownInterface.inc.php @@ -0,0 +1,9 @@ + + * @copyright 2004-2019 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + +namespace md; + +/** + * Markdown Parser Interface + */ +interface MarkdownInterface { + /** + * Initialize the parser and return the result of its transform method. + * This will work fine for derived classes too. + * + * @api + * + * @param string $text + * @return string + */ + public static function defaultTransform($text); + + /** + * Main function. Performs some preprocessing on the input text + * and pass it through the document gamut. + * + * @api + * + * @param string $text + * @return string + */ + public function transform($text); +} diff --git a/php/404.php b/php/404.php new file mode 100644 index 0000000..43fed61 --- /dev/null +++ b/php/404.php @@ -0,0 +1,21 @@ + + + + + + + + +Page not found + + +
    +

    The page you requested was not found. It's possible that it was deleted, moved, or never existed in the first place. If you're unsure, you might want to check the wiki commit history.

    + +
    + + diff --git a/php/blog-p.php b/php/blog-p.php new file mode 100644 index 0000000..de56950 --- /dev/null +++ b/php/blog-p.php @@ -0,0 +1,25 @@ + + + + + + + +
    +

    Blog

    +

    I repost some of my RSS feed articles/posts here sometimes. This is a view of all of them.

    +

    NOTE: You can see all of them using my RSS feed.

    +

    Feeds

    +

    This is a list of feeds containing the complete list of blog posts. You can add any of these to your RSS reader and read at any time, provided you have an internet connection.

    +

    If you do not have a reader, install newsboat with your GNU/Linux distribution's package manager.

    + +

    Articles

    +

    These are all articles I've posted. For archived articles (post 49 and earlier), see the RSS feeds.

    + +
    +