add posts, edit posts
This commit is contained in:
@@ -1,122 +1,138 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Meta",
|
||||
"slug": "meta",
|
||||
"filename": "meta",
|
||||
"date": "01/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["meta", "code", "project", "web", "markdown", "typescript_javascript", "css"]
|
||||
},
|
||||
"llm": {
|
||||
"title": "LLM",
|
||||
"slug": "llm",
|
||||
"filename": "llm",
|
||||
"date": "16/09/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["opinion"]
|
||||
},
|
||||
"hex-to-bytes-and-back": {
|
||||
"title": "Hex to Bytes and Back",
|
||||
"slug": "hex-to-bytes-and-back",
|
||||
"filename": "hex_to_bytes_and_back",
|
||||
"date": "15/09/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["typescript_javascript", "code", "math"]
|
||||
},
|
||||
"rss-feed": {
|
||||
"title": "RSS!",
|
||||
"slug": "rss-feed",
|
||||
"filename": "rss_feed",
|
||||
"date": "19/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["meta", "typescript_javascript", "project", "web"]
|
||||
},
|
||||
"fermats-little-theorem": {
|
||||
"title": "Fermats Little Theorem",
|
||||
"slug": "fermats-little-theorem",
|
||||
"filename": "fermats_little_theorem",
|
||||
"date": "12/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "typescript_javascript", "math"]
|
||||
},
|
||||
"wikipedia-rabbitholes": {
|
||||
"title": "Wikipedia Rabbitholes",
|
||||
"slug": "wikipedia-rabbitholes",
|
||||
"filename": "wikipedia_rabbitholes",
|
||||
"date": "09/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["reading", "history", "wikipedia"]
|
||||
},
|
||||
"eve": {
|
||||
"title": "Eve",
|
||||
"slug": "eve",
|
||||
"filename": "eve",
|
||||
"date": "06/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["cryptography"]
|
||||
},
|
||||
"month-start-unix": {
|
||||
"title": "Finding the Unix Timestamp of the Start of the Month with Javascript",
|
||||
"slug": "month-start-unix",
|
||||
"filename": "month_start_unix",
|
||||
"date": "01/04/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "web", "typescript_javascript"]
|
||||
},
|
||||
"190k-faucet": {
|
||||
"title": "190000 Payouts!",
|
||||
"slug": "190-faucet",
|
||||
"filename": "190k_faucet",
|
||||
"date": "12/02/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["project", "web", "milestone", "cryptocurrency"]
|
||||
},
|
||||
"adding-commas": {
|
||||
"title": "Adding Commas to Numbers",
|
||||
"slug": "adding-commas",
|
||||
"filename": "adding_commas",
|
||||
"date": "15/11/2022",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "typescript_javascript"]
|
||||
},
|
||||
"solving-problems-with-a-timeout": {
|
||||
"title": "Solving Problems With a Timeout",
|
||||
"slug": "solving-problems-with-a-timeout",
|
||||
"filename": "solving_problems_with_a_timeout",
|
||||
"date": "19/08/2022",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["bot", "typescript_javascript"]
|
||||
},
|
||||
"gobanme-v1-2": {
|
||||
"title": "GoBanMe v1.2",
|
||||
"slug": "gobanme-v1-2",
|
||||
"filename": "gobanme_v1-2",
|
||||
"date": "30/05/2022",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["release", "cryptocurrency"]
|
||||
},
|
||||
"fake-typing-effect": {
|
||||
"title": "Making a Fake Typing Effect",
|
||||
"slug": "fake-typing-effect",
|
||||
"filename": "fake_typing_effect",
|
||||
"date": "27/01/2022",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "web", "typescript_javascript"]
|
||||
},
|
||||
"ryuji-docs": {
|
||||
"title": "Ryuji Documentation",
|
||||
"slug": "ryuji-docs",
|
||||
"filename": "ryuji_docs",
|
||||
"date": "02/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "project", "web", "docs", "typescript_javascript"]
|
||||
},
|
||||
"saki-docs": {
|
||||
"title": "Saki Documentation",
|
||||
"slug": "saki-docs",
|
||||
"filename": "saki_docs",
|
||||
"date": "02/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "project", "web", "build", "docs", "typescript_javascript"]
|
||||
}
|
||||
}
|
||||
{
|
||||
"meta": {
|
||||
"title": "Meta",
|
||||
"slug": "meta",
|
||||
"filename": "meta",
|
||||
"date": "01/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["meta", "code", "project", "web", "markdown", "typescript_javascript", "css"]
|
||||
},
|
||||
"downloading-my-spotify-playlist-for-free": {
|
||||
"title": "Downloading my Spotify Playlist for Free",
|
||||
"slug": "downloading-my-spotify-playlist-for-free",
|
||||
"filename": "downloading_my_spotify_playlist_for_free",
|
||||
"date": "27/10/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "typescript_javascript", "bash"]
|
||||
},
|
||||
"ryuji-rust": {
|
||||
"title": "Ryuji Rust",
|
||||
"slug": "ryuji-rust",
|
||||
"filename": "ryuji_rust",
|
||||
"date": "27/10/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["rust", "project"]
|
||||
},
|
||||
"llm": {
|
||||
"title": "LLM",
|
||||
"slug": "llm",
|
||||
"filename": "llm",
|
||||
"date": "16/09/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["opinion"]
|
||||
},
|
||||
"hex-to-bytes-and-back": {
|
||||
"title": "Hex to Bytes and Back",
|
||||
"slug": "hex-to-bytes-and-back",
|
||||
"filename": "hex_to_bytes_and_back",
|
||||
"date": "15/09/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["typescript_javascript", "code", "math"]
|
||||
},
|
||||
"rss-feed": {
|
||||
"title": "RSS!",
|
||||
"slug": "rss-feed",
|
||||
"filename": "rss_feed",
|
||||
"date": "19/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["meta", "typescript_javascript", "project", "web"]
|
||||
},
|
||||
"fermats-little-theorem": {
|
||||
"title": "Fermats Little Theorem",
|
||||
"slug": "fermats-little-theorem",
|
||||
"filename": "fermats_little_theorem",
|
||||
"date": "12/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "typescript_javascript", "math"]
|
||||
},
|
||||
"wikipedia-rabbitholes": {
|
||||
"title": "Wikipedia Rabbitholes",
|
||||
"slug": "wikipedia-rabbitholes",
|
||||
"filename": "wikipedia_rabbitholes",
|
||||
"date": "09/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["reading", "history", "wikipedia"]
|
||||
},
|
||||
"eve": {
|
||||
"title": "Eve",
|
||||
"slug": "eve",
|
||||
"filename": "eve",
|
||||
"date": "06/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["cryptography"]
|
||||
},
|
||||
"month-start-unix": {
|
||||
"title": "Finding the Unix Timestamp of the Start of the Month with Javascript",
|
||||
"slug": "month-start-unix",
|
||||
"filename": "month_start_unix",
|
||||
"date": "01/04/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "web", "typescript_javascript"]
|
||||
},
|
||||
"190k-faucet": {
|
||||
"title": "190000 Payouts!",
|
||||
"slug": "190-faucet",
|
||||
"filename": "190k_faucet",
|
||||
"date": "12/02/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["project", "web", "milestone", "cryptocurrency"]
|
||||
},
|
||||
"adding-commas": {
|
||||
"title": "Adding Commas to Numbers",
|
||||
"slug": "adding-commas",
|
||||
"filename": "adding_commas",
|
||||
"date": "15/11/2022",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "typescript_javascript"]
|
||||
},
|
||||
"solving-problems-with-a-timeout": {
|
||||
"title": "Solving Problems With a Timeout",
|
||||
"slug": "solving-problems-with-a-timeout",
|
||||
"filename": "solving_problems_with_a_timeout",
|
||||
"date": "19/08/2022",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["bot", "typescript_javascript"]
|
||||
},
|
||||
"gobanme-v1-2": {
|
||||
"title": "GoBanMe v1.2",
|
||||
"slug": "gobanme-v1-2",
|
||||
"filename": "gobanme_v1-2",
|
||||
"date": "30/05/2022",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["release", "cryptocurrency"]
|
||||
},
|
||||
"fake-typing-effect": {
|
||||
"title": "Making a Fake Typing Effect",
|
||||
"slug": "fake-typing-effect",
|
||||
"filename": "fake_typing_effect",
|
||||
"date": "27/01/2022",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "web", "typescript_javascript"]
|
||||
},
|
||||
"ryuji-docs": {
|
||||
"title": "Ryuji Documentation",
|
||||
"slug": "ryuji-docs",
|
||||
"filename": "ryuji_docs",
|
||||
"date": "02/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "project", "web", "docs", "typescript_javascript"]
|
||||
},
|
||||
"saki-docs": {
|
||||
"title": "Saki Documentation",
|
||||
"slug": "saki-docs",
|
||||
"filename": "saki_docs",
|
||||
"date": "02/08/2023",
|
||||
"author": "jetstream0/Prussia",
|
||||
"tags": ["code", "project", "web", "build", "docs", "typescript_javascript"]
|
||||
}
|
||||
}
|
||||
|
||||
74
posts/downloading_my_spotify_playlist_for_free.md
Normal file
74
posts/downloading_my_spotify_playlist_for_free.md
Normal file
@@ -0,0 +1,74 @@
|
||||
Like most people, I like listening to music.
|
||||
|
||||
Also like most people, I don't like listening to ads or paying subscriptions^\[0\]^. Spotify's free tier is pretty good, and I can block their ads by using the web player and uBlock Origin.
|
||||
|
||||
I'm mostly content with that, but there are still some annoyances - I can't listen offline, the UI is a little frustrating, and even though the ads are blocked, the player still sometimes freezes when an ad is supposed to be playing (so the next song isn't played, have to reload the page). Combined with not morally being a fan of relying on a for-profit third-party service for my music, I decided today to write a few scripts to download all the songs on my favourite Spotify playlist (around 60 songs).
|
||||
|
||||
First step is getting all the song and artist names on my playlist from Spotify. I did find an [Spotify API endpoint](https://developer.spotify.com/documentation/web-api/reference/get-playlists-tracks), but it seemed like a pain with OAuth required. Instead, I just opened the playlist in my browser. After scrolling down to load all the playlist tracks, I ran something similar to the following to get all the track names:
|
||||
|
||||
```javascript
|
||||
[...document.querySelectorAll(".iCQtmPqY0QvkumAOuCjr")].map((d) => d.innerText)
|
||||
```
|
||||
|
||||
After a bit of processing with Javascript, vim find-and-replace commands, and a few manual corrections, I ended up with a `songs.txt` file in this format:
|
||||
|
||||
```
|
||||
1|Alice in Freezer|Orangestar
|
||||
2|無人駅|n-buna
|
||||
...and so on
|
||||
```
|
||||
|
||||
Now that we have all the song and artist names, we need to fetch the Youtube urls of the songs, so we can download them with [yt-dlp](https://github.com/yt-dlp/yt-dlp).
|
||||
|
||||
It turns out the Youtube search API also needs an API key, so I used the [usetube](https://github.com/valerebron/usetube) npm package, which scrapes the actual web page instead of using the API. Here's the code:
|
||||
|
||||
```javascript
|
||||
const fs = require("fs");
|
||||
const yt = require("usetube");
|
||||
|
||||
async function main() {
|
||||
let songs = fs.readFileSync("../songs.txt", "utf-8").split("\n");
|
||||
for (let i = 0; i < songs.length; i++) {
|
||||
let song_name = songs[i].split("|")[1];
|
||||
let artist_name = songs[i].split("|")[2];
|
||||
console.log(song_name+" "+artist_name);
|
||||
const videos = (await yt.searchVideo(song_name+" "+artist_name)).videos;
|
||||
songs[i] = songs[i]+"|https://youtube.com/watch?v="+videos[0].id;
|
||||
console.log(songs[i].split("|")[3]);
|
||||
}
|
||||
fs.writeFileSync("../songs.txt", songs.join("\n"), "utf-8");
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
Now `songs.txt` looks a little like this:
|
||||
|
||||
```
|
||||
1|Alice in Freezer|Orangestar|https://youtube.com/watch?v=jQmYZWjLwzw
|
||||
2|無人駅|n-buna|https://youtube.com/watch?v=G8PFPUCNOg4
|
||||
...and so on
|
||||
```
|
||||
|
||||
The final step is just writing a bash script to download all the songs. I don't really know much bash, but after a few StackOverflow searches, I got a working script:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
while IFS= read -r line; do
|
||||
IFS='|' read -ra ADDR <<< "$line"
|
||||
for i in "${!ADDR[@]}"; do
|
||||
printf "\n${ADDR[$i]}"
|
||||
if [ $i -eq 3 ]; then
|
||||
yt_dlp -x --audio-format mp3 "${ADDR[$i]}"
|
||||
fi
|
||||
done
|
||||
done < songs.txt
|
||||
```
|
||||
|
||||
Yay!
|
||||
|
||||
This was a pretty "boring" project that didn't involve much thinking or code. But being able to automate small, tedious stuff like this is a pretty underrated perk of having even a little programming knowledge.
|
||||
|
||||
===
|
||||
- \[0\]: It's almost like artists are people too, and need to make money to support themselves! In all seriousness though, Spotify pays artists something like $0.003 USD per stream. It makes much more sense to support them through buying albums or going to concerts, instead of wasting time listening to ads.
|
||||
371
posts/meta.md
371
posts/meta.md
@@ -1,184 +1,187 @@
|
||||
There used to be a different blog here. But it wasn't very good, [code](https://github.com/jetstream0/Markup-to-HTML) *and* writing-wise. So I decided to rewrite everything.
|
||||
|
||||
The old blog was an express server that looked for `.md` files in a directory, converted them to HTML, and served it. That worked mostly fine. However, the converter didn't support many Markdown features, and was pretty buggy. Using an express server also meant that the site wasn't static, and had limited options for hosting.
|
||||
|
||||
Replit's free tier was pretty unreliable, and Render only allowed one free web service per account, which I was already using to run my [faucet](https://faucet.prussia.dev). I could've created a new Render account, but they recently started requiring credit card verification, which I didn't really want to do.
|
||||
|
||||
Besides, making the blog static instead of relying on an express server wouldn't be that hard. A month before, I had already wrote a better (?) or at least more fully featured Markdown to HTML parser, [Makoto](https://github.com/jetstream0/Makoto-Markdown-to-HTML), so that was already one of the problems with the old blog solved.
|
||||
|
||||
Anyways, once I decided to start completely rewriting the blog, I established some goals that I wanted the new blog to accomplish.
|
||||
|
||||
## Technical Goals
|
||||
- Static, so it can be deployed by eg, Github Pages or Cloudflare Pages
|
||||
- Built from scratch with no third-party dependencies (builtin modules like `path` and `fs` are ok of course, `makoto` is not third party, also doesn't count)
|
||||
- Use Typescript
|
||||
- No Javascript running client side - the web pages should be pure HTML and CSS
|
||||
- Style-wise, should be minimalistic, nothing fancy
|
||||
- Load quickly and be small in size
|
||||
|
||||
## Non-Technical Goals
|
||||
- Make two things I can call "Ryuji" and "Saki" to go along with "Makoto" (those are the three main characters of one of the best manga series ever)
|
||||
- Move over some of the old blog posts (only the stuff I like), after rewriting them
|
||||
- Start writing stuff on the blog again, at least semi-regularly
|
||||
|
||||
## Code
|
||||
Hedgeblog (oh, that's what I'm calling it by the way) is made of three components: Makoto (Markdown to HTML parser), Ryuji (templating language), and Saki (build system).
|
||||
|
||||
You can find the code on [Github](https://github.com/jetstream0/hedgeblog).
|
||||
|
||||
### Makoto
|
||||
Makoto is the Markdown-to-HTML parser, made with no dependencies. It was made around two months before Ryuji and Saki, and is meant to be more of a standalone thing. This is the sole npm dependency of the project. I `npm install`ed it instead of just copying the file over mostly because I published Makoto to npm and wanted to make sure it worked. Also, it has a different license, documentation and stuff.
|
||||
|
||||
All the standard Markdown are supported (headers, bolds, italics, images, links, blockquotes, unordered lists, ordered lists, code, code blocks...), as well as superscripts and tables (although tables are probably buggy). Makoto also does some pretty neat stuff like passing on the language of the code block (if given) as a class in the resulting div: `code-<language>`, or automatically add ids to headers, so they can have anchor links.
|
||||
|
||||
It also has a very cool warnings feature, which isn't used in this project, but can be seen in action if you use the [Makoto Web Editor](https://makoto.prussia.dev).
|
||||
|
||||
### Ryuji
|
||||
Ryuji is a simple templating system that supports `if` statements, `for` loops, components, and inserting variables. It isn't quite as fully featured as Jinja/Nunjucks, but on the upside, Ryuji is less than 280 lines of code, and worked very well for my usecase. I think it's pretty cool.
|
||||
|
||||
Here's a quick overview of the syntax:
|
||||
|
||||
```html
|
||||
[[ component:navbar ]] <!--this looks for templates/components/navbar.html and displays it here-->
|
||||
<p>You can insert variables. My favourite food is: [[ favourite_food ]]</p>
|
||||
<p>And make sure the variable is truthy then do something.</p>
|
||||
[[ if:show_secrets ]]
|
||||
<ul>
|
||||
<li>Secret 1: lorem ipsum</li>
|
||||
<li>Secret 2: My favourite is not actually [[ favourite_food ]]</li>
|
||||
</ul>
|
||||
[[ endif ]]
|
||||
<div>
|
||||
<p>Variables are by default sanitized so HTML/CSS/JS can't actually be executed, but you can disable this.</p>
|
||||
[[ html:html_from_database ]]
|
||||
</div>
|
||||
[[ for:members:member ]]
|
||||
<p><b>[[ member ]]</b> is a proud member of our group!</p>
|
||||
[[ endfor ]]
|
||||
```
|
||||
|
||||
After finishing writing Ryuji, and writing some tests to make sure it all worked, I realized that I needed a few features that were missing.
|
||||
|
||||
There was no way to see the current index in a for loop, or the max index (length-1) of whatever variable we were looping over. This was needed for the tag links in the post.
|
||||
|
||||
In addition, if statements only checked if the variable was truthy (not `false` or `0` or `""`), but I needed if statements making sure two variables were equal, as well as if statements making sure two variables were *not* equal. You can see this being used in the post's tags along with the new for loop features, as well as the "Next Post" link at the bottom of the post.
|
||||
|
||||
So, I added those features. Let's take a look of these new features being used to show and link post tags.
|
||||
|
||||
Formatting the code a little nicer, this is what it looks like:
|
||||
|
||||
```
|
||||
[[ for:post.tags:tag:index:max ]]
|
||||
<a href="/tags/[[ tag ]]">[[ tag ]]</a>[[ if:index:!max ]], [[ endif ]]
|
||||
[[ endfor ]]
|
||||
```
|
||||
|
||||
Ok, in the first line (`for:post.tags:tag:index:max`), we are looping over the variable `post.tags`, and assigning each item in `post.tags` as the variable `tag`. That's nothing new, what's new is the `:index:max` portion. `index` is the index variable, starting at 0 and incrementing every loop, while `max` is the maximum index (the length of the variable to loop over - 1).
|
||||
|
||||
If you look at the Ryuji code, now you can see that it is looping over the tags of the post, and creating a link for each tag. If the tag is *not* the last tag (`index` is not equal to `max`), we will also add a comma (and a space).
|
||||
|
||||
Here's the equivalent python code, if it helps:
|
||||
|
||||
```python
|
||||
html = ""
|
||||
max = len(post.tags)-1
|
||||
index = 0
|
||||
for tag in post.tags:
|
||||
html += "<a href=\"/tags/"+tag+"\">"+tag+"</a>"
|
||||
if index != max:
|
||||
html += ","
|
||||
index += 1
|
||||
```
|
||||
|
||||
While Ryuji is meant for HTML, there is no reason it can't be used for other formats.
|
||||
|
||||
Take a look at the [docs](/posts/ryuji-docs) for Ryuji.
|
||||
|
||||
### Saki
|
||||
Saki is the build system that uses Ryuji templates to generate all the HTML files, and then outputs everything (including static files, of course) to the `build` directory. Even more simple than Ryuji, it is just around 70 lines of code.
|
||||
|
||||
Here are the very short [docs](/posts/saki-docs) for Saki.
|
||||
|
||||
## Putting It All Together
|
||||
When building, the program (`index.ts`) reads `/posts/_metadata.json` and passes all the post metadata information to the `templates/index.html` template, which is the home page! Then, it renders all the posts with the `templates/post.html` template and outputs to `/posts/*`. Next, it looks again at the post metadata and gets all the tags used. Once it has all the tags, pages for the tags are generated at `/tags/*`. That page lists all the posts with that tag. Scroll up and try it! It also outputs the `static` directory, as well, static files.
|
||||
|
||||
> ### Tip: Serve Without The `.html`
|
||||
> Say we want to serve a HTML file at `/posts/example` instead of `/posts/example.html`. Just create a directory called `example` and put `example.html` inside it, renaming it `index.html`.
|
||||
> Basically, `/posts/example.html` becomes `/posts/example/index.html`, and now the HTML file is served at `/posts/example`. You probably already knew that, but if you didn't now you know ^\[citation needed]^.
|
||||
|
||||
## Buttons Without Javascript
|
||||
If you think back to around 950 words ago, you may recall that this site has zero frontend Javascript (or WebAssembly, as cool as it is). If you didn't recall that, I just reminded you. I will be sending an invoice later.
|
||||
|
||||
So how does the "Show MD", "Fancy Title", and Dark/Light theme toggle work? The key thing here is that all three of these are checkboxes. Yes, even the Dark/Light theme toggle is a checkbox. That toggle hides its checkbox and takes advantage of the fact you can click on a `<label>` with an appropriate `for` attribute to toggle a checkbox, and uses the `::after` psuedo-element to change the content between the moon emoji and the sun emoji, depending on the state of the checkbox.
|
||||
|
||||
What's so special about checkboxes? The `:checked` ([see MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/:checked)) property, that's what! With the `:checked` property, we can apply styles depending on whether a checkbox is checked. See the following, which scales the checkbox by 3x when the checkbox is checked:
|
||||
|
||||
```css
|
||||
input[type="checkbox"] {
|
||||
display: inline-block;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked {
|
||||
transform: scale(3);
|
||||
}
|
||||
```
|
||||
|
||||
And because of the `a ~ b` (select selector b *after* selector a) and `a + b` (select selector b *immediately after* selector a) CSS selectors, we can change the properties of other elements. Unfortunately, there doesn't seem to be a pure CSS way to change the style of elements *before* the checkbox. There are ways around this, like putting the checkbox before the desired element in the code, but using `position: relative`, `position: absolute`, and other ways to make the checkbox visually look like it is after the desired element. I didn't really want to do that though, so you can notice that all the checkboxes on this website are before the element whose style they change.
|
||||
|
||||
Here's a real example. The following CSS makes the "Show MD" checkbox functional:
|
||||
|
||||
```css
|
||||
#post-md {
|
||||
margin-top: 7px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#show-md:checked ~ #post-md {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#show-md:checked ~ #post-html {
|
||||
display: none;
|
||||
}
|
||||
```
|
||||
|
||||
## Other Style Notes
|
||||
I used Verdana for headers, Courier New for code, and Times New Roman for everything else. These fonts were chosen mostly because they are websafe, ie included in most OSes. You cannot stop me from using Times New Roman. I like the look.
|
||||
|
||||
The colour for visited links is `orchid`, and the colour for non-visited links is `forestgreen`.
|
||||
|
||||
Since this blog is basically for my own "enjoyment", and doesn't need to look "sleek" or "professional", this site's design philosophy is moreso a rejection of those overdesigned corporate sites with too many popups, as well as certain React (or other framework) sites that don't even load with Javascript disabled, than a specific set of tenets. Combined with the fact that choosing colour schemes makes me angry, don't expect very consistent or aesthetic designs.
|
||||
|
||||
But I'll try my best.
|
||||
|
||||
## Running
|
||||
|
||||
After `git clone`ing the repo, `cd` into the directory and install the (sole) dependency:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
To build:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
To build and preview locally at `http://localhost:8042`:
|
||||
|
||||
```bash
|
||||
npm run preview
|
||||
```
|
||||
|
||||
To run tests for Ryuji:
|
||||
|
||||
```bash
|
||||
npm run test
|
||||
```
|
||||
|
||||
## Todo
|
||||
In the future, I would love to have those fun box gifs you used to see on geocities and other websites (like the ones on the bottom of the [pensquid](https://pensquid.net/) website), plus also something similar to [Wikipedia Userboxes](https://en.wikipedia.org/wiki/Wikipedia:Userboxes).
|
||||
|
||||
And I'll keep improving the site and fixing bugs, and occasionally write articles for the roughly four readers of this blog.
|
||||
There used to be a different blog here. But it wasn't very good, [code](https://github.com/jetstream0/Markup-to-HTML) *and* writing-wise. So I decided to rewrite everything.
|
||||
|
||||
The old blog was an express server that looked for `.md` files in a directory, converted them to HTML, and served it. That worked mostly fine. However, the converter didn't support many Markdown features, and was pretty buggy. Using an express server also meant that the site wasn't static, and had limited options for hosting.
|
||||
|
||||
Replit's free tier was pretty unreliable, and Render only allowed one free web service per account, which I was already using to run my [faucet](https://faucet.prussia.dev). I could've created a new Render account, but they recently started requiring credit card verification, which I didn't really want to do.
|
||||
|
||||
Besides, making the blog static instead of relying on an express server wouldn't be that hard. A month before, I had already wrote a better (?) or at least more fully featured Markdown to HTML parser, [Makoto](https://github.com/jetstream0/Makoto-Markdown-to-HTML), so that was already one of the problems with the old blog solved.
|
||||
|
||||
Anyways, once I decided to start completely rewriting the blog, I established some goals that I wanted the new blog to accomplish.
|
||||
|
||||
## Technical Goals
|
||||
- Static, so it can be deployed by eg, Github Pages or Cloudflare Pages
|
||||
- Built from scratch with no third-party dependencies (builtin modules like `path` and `fs` are ok of course, `makoto` is not third party, also doesn't count)
|
||||
- Use Typescript
|
||||
- No Javascript running client side - the web pages should be pure HTML and CSS
|
||||
- Style-wise, should be minimalistic, nothing fancy
|
||||
- Load quickly and be small in size
|
||||
|
||||
## Non-Technical Goals
|
||||
- Make two things I can call "Ryuji" and "Saki" to go along with "Makoto" (those are the three main characters of one of the best manga series ever)
|
||||
- Move over some of the old blog posts (only the stuff I like), after rewriting them
|
||||
- Start writing stuff on the blog again, at least semi-regularly
|
||||
|
||||
## Code
|
||||
Hedgeblog (oh, that's what I'm calling it by the way) is made of three components: Makoto (Markdown to HTML parser), Ryuji (templating language), and Saki (build system).
|
||||
|
||||
You can find the code on [Github](https://github.com/jetstream0/hedgeblog).
|
||||
|
||||
### Makoto
|
||||
Makoto is the Markdown-to-HTML parser, made with no dependencies. It was made around two months before Ryuji and Saki, and is meant to be more of a standalone thing. This is the sole npm dependency of the project. I `npm install`ed it instead of just copying the file over mostly because I published Makoto to npm and wanted to make sure it worked. Also, it has a different license, documentation and stuff.
|
||||
|
||||
All the standard Markdown are supported (headers, bolds, italics, images, links, blockquotes, unordered lists, ordered lists, code, code blocks...), as well as superscripts and tables (although tables are probably buggy). Makoto also does some pretty neat stuff like passing on the language of the code block (if given) as a class in the resulting div: `code-<language>`, or automatically add ids to headers, so they can have anchor links.
|
||||
|
||||
It also has a very cool warnings feature, which isn't used in this project, but can be seen in action if you use the [Makoto Web Editor](https://makoto.prussia.dev).
|
||||
|
||||
### Ryuji
|
||||
Ryuji is a simple templating system that supports `if` statements, `for` loops, components, and inserting variables. It isn't quite as fully featured as Jinja/Nunjucks, but on the upside, Ryuji is less than 280 lines of code, and worked very well for my usecase. I think it's pretty cool.
|
||||
|
||||
Here's a quick overview of the syntax:
|
||||
|
||||
```html
|
||||
[[ component:navbar ]] <!--this looks for templates/components/navbar.html and displays it here-->
|
||||
<p>You can insert variables. My favourite food is: [[ favourite_food ]]</p>
|
||||
<p>And make sure the variable is truthy then do something.</p>
|
||||
[[ if:show_secrets ]]
|
||||
<ul>
|
||||
<li>Secret 1: lorem ipsum</li>
|
||||
<li>Secret 2: My favourite is not actually [[ favourite_food ]]</li>
|
||||
</ul>
|
||||
[[ endif ]]
|
||||
<div>
|
||||
<p>Variables are by default sanitized so HTML/CSS/JS can't actually be executed, but you can disable this.</p>
|
||||
[[ html:html_from_database ]]
|
||||
</div>
|
||||
[[ for:members:member ]]
|
||||
<p><b>[[ member ]]</b> is a proud member of our group!</p>
|
||||
[[ endfor ]]
|
||||
```
|
||||
|
||||
After finishing writing Ryuji, and writing some tests to make sure it all worked, I realized that I needed a few features that were missing.
|
||||
|
||||
There was no way to see the current index in a for loop, or the max index (length-1) of whatever variable we were looping over. This was needed for the tag links in the post.
|
||||
|
||||
In addition, if statements only checked if the variable was truthy (not `false` or `0` or `""`), but I needed if statements making sure two variables were equal, as well as if statements making sure two variables were *not* equal. You can see this being used in the post's tags along with the new for loop features, as well as the "Next Post" link at the bottom of the post.
|
||||
|
||||
So, I added those features. Let's take a look of these new features being used to show and link post tags.
|
||||
|
||||
Formatting the code a little nicer, this is what it looks like:
|
||||
|
||||
```
|
||||
[[ for:post.tags:tag:index:max ]]
|
||||
<a href="/tags/[[ tag ]]">[[ tag ]]</a>[[ if:index:!max ]], [[ endif ]]
|
||||
[[ endfor ]]
|
||||
```
|
||||
|
||||
Ok, in the first line (`for:post.tags:tag:index:max`), we are looping over the variable `post.tags`, and assigning each item in `post.tags` as the variable `tag`. That's nothing new, what's new is the `:index:max` portion. `index` is the index variable, starting at 0 and incrementing every loop, while `max` is the maximum index (the length of the variable to loop over - 1).
|
||||
|
||||
If you look at the Ryuji code, now you can see that it is looping over the tags of the post, and creating a link for each tag. If the tag is *not* the last tag (`index` is not equal to `max`), we will also add a comma (and a space).
|
||||
|
||||
Here's the equivalent python code, if it helps:
|
||||
|
||||
```python
|
||||
html = ""
|
||||
max = len(post.tags)-1
|
||||
index = 0
|
||||
for tag in post.tags:
|
||||
html += "<a href=\"/tags/"+tag+"\">"+tag+"</a>"
|
||||
if index != max:
|
||||
html += ","
|
||||
index += 1
|
||||
```
|
||||
|
||||
While Ryuji is meant for HTML, there is no reason it can't be used for other formats.
|
||||
|
||||
Take a look at the [docs](/posts/ryuji-docs) for Ryuji.
|
||||
|
||||
### Saki
|
||||
Saki is the build system that uses Ryuji templates to generate all the HTML files, and then outputs everything (including static files, of course) to the `build` directory. Even more simple than Ryuji, it is just around 70 lines of code.
|
||||
|
||||
Here are the very short [docs](/posts/saki-docs) for Saki.
|
||||
|
||||
## Putting It All Together
|
||||
When building, the program (`index.ts`) reads `/posts/_metadata.json` and passes all the post metadata information to the `templates/index.html` template, which is the home page! Then, it renders all the posts with the `templates/post.html` template and outputs to `/posts/*`. Next, it looks again at the post metadata and gets all the tags used. Once it has all the tags, pages for the tags are generated at `/tags/*`. That page lists all the posts with that tag. Scroll up and try it! It also outputs the `static` directory, as well, static files.
|
||||
|
||||
> ### Tip: Serve Without The `.html`
|
||||
> Say we want to serve a HTML file at `/posts/example` instead of `/posts/example.html`. Just create a directory called `example` and put `example.html` inside it, renaming it `index.html`.
|
||||
> Basically, `/posts/example.html` becomes `/posts/example/index.html`, and now the HTML file is served at `/posts/example`. You probably already knew that, but if you didn't now you know ^\[citation needed]^.
|
||||
|
||||
## Buttons Without Javascript
|
||||
If you think back to around 950 words ago, you may recall that this site has zero frontend Javascript (or WebAssembly, as cool as it is). If you didn't recall that, I just reminded you. I will be sending an invoice later.
|
||||
|
||||
So how does the "Show MD", "Fancy Title", and Dark/Light theme toggle work? The key thing here is that all three of these are checkboxes. Yes, even the Dark/Light theme toggle is a checkbox. That toggle hides its checkbox and takes advantage of the fact you can click on a `<label>` with an appropriate `for` attribute to toggle a checkbox, and uses the `::after` psuedo-element to change the content between the moon emoji and the sun emoji, depending on the state of the checkbox.
|
||||
|
||||
What's so special about checkboxes? The `:checked` ([see MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/:checked)) property, that's what! With the `:checked` property, we can apply styles depending on whether a checkbox is checked. See the following, which scales the checkbox by 3x when the checkbox is checked:
|
||||
|
||||
```css
|
||||
input[type="checkbox"] {
|
||||
display: inline-block;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked {
|
||||
transform: scale(3);
|
||||
}
|
||||
```
|
||||
|
||||
And because of the `a ~ b` (select selector b *after* selector a) and `a + b` (select selector b *immediately after* selector a) CSS selectors, we can change the properties of other elements. Unfortunately, there doesn't seem to be a pure CSS way to change the style of elements *before* the checkbox. There are ways around this, like putting the checkbox before the desired element in the code, but using `position: relative`, `position: absolute`, and other ways to make the checkbox visually look like it is after the desired element. I didn't really want to do that though, so you can notice that all the checkboxes on this website are before the element whose style they change.
|
||||
|
||||
Here's a real example. The following CSS makes the "Show MD" checkbox functional:
|
||||
|
||||
```css
|
||||
#post-md {
|
||||
margin-top: 7px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#show-md:checked ~ #post-md {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#show-md:checked ~ #post-html {
|
||||
display: none;
|
||||
}
|
||||
```
|
||||
|
||||
## Other Style Notes
|
||||
I used Verdana for headers, Courier New for code, and Times New Roman for everything else. These fonts were chosen mostly because they are websafe, ie included in most OSes. You cannot stop me from using Times New Roman. I like the look.
|
||||
|
||||
The colour for visited links is `orchid`, and the colour for non-visited links is `forestgreen`.
|
||||
|
||||
Since this blog is basically for my own "enjoyment", and doesn't need to look "sleek" or "professional", this site's design philosophy is moreso a rejection of those overdesigned corporate sites with too many popups, as well as certain React (or other framework) sites that don't even load with Javascript disabled, than a specific set of tenets. Combined with the fact that choosing colour schemes makes me angry, don't expect very consistent or aesthetic designs.
|
||||
|
||||
But I'll try my best.
|
||||
|
||||
## Running
|
||||
|
||||
After `git clone`ing the repo, `cd` into the directory and install the (sole) dependency:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
To build:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
To build and preview locally at `http://localhost:8042`:
|
||||
|
||||
```bash
|
||||
npm run preview
|
||||
```
|
||||
|
||||
To run tests for Ryuji:
|
||||
|
||||
```bash
|
||||
npm run test
|
||||
```
|
||||
|
||||
## Todo
|
||||
In the future, I would love to have those fun box gifs^\[0\]^ you used to see on geocities and other websites (like the ones on the bottom of the [pensquid](https://pensquid.net/) website), plus also something similar to [Wikipedia Userboxes](https://en.wikipedia.org/wiki/Wikipedia:Userboxes).
|
||||
|
||||
And I'll keep improving the site and fixing bugs, and occasionally write articles for the roughly four readers of this blog.
|
||||
|
||||
===
|
||||
- \[0\]: This has been done! Plus, there's a [RSS feed](/posts/rss-feed) now too.
|
||||
|
||||
5
posts/ryuji_rust.md
Normal file
5
posts/ryuji_rust.md
Normal file
@@ -0,0 +1,5 @@
|
||||
A month or two ago, I "translated" [Ryuji](/posts/ryuji-docs), originally written in Typescript, into Rust.
|
||||
|
||||
I mostly wrote this to practice writing Rust, which I guess is a success. In this project, I've somehow once again avoided properly figuring out how to use lifetimes (hey, I tried). That's a victory for my brain but probably a failure for my Rust skills.
|
||||
|
||||
The source code is on [Github](https://github.com/jetstream0/ryuji-rust) and the auto-generated documentation is on [docs.rs](https://docs.rs/ryuji-rust/latest/ryuji_rust/). If, for whatever reason, you actually want to use Ryuji-Rust, it might be helpful to look at the [tests](https://github.com/jetstream0/ryuji-rust/blob/master/src/lib.rs), [example](https://github.com/jetstream0/ryuji-rust/tree/master/example), and the [Ryuji docs](/posts/ryuji-docs) page.
|
||||
@@ -1,21 +1,21 @@
|
||||
Recently, I've been working on a discord bot game for Beer Goggles NFT on Algorand.
|
||||
|
||||
The specifics aren't too important, but essentially the game works like this: A game is started by an admin, and a secret number of hp is specified. Then, players can click a button, and depending on the amount of NFTs they hold, they will do "damage". All the damage is added up, and the person who crosses the secret number of hp wins. Like a pinata. Or in the case of our bar themed game, a huge opaque mug of beer that is passed around, with the goal being the one to finish the drink.
|
||||
|
||||
Now, onto the more technical details. Whenever a user clicks the button, the callback for the button interaction event is run.
|
||||
|
||||
First, the program reads the database (MongoDB) and sees the current hp left for the current game. If the current hp is less than zero, or a game over flag is set, the user is notified that the game is over, and the click does nothing. If that isn't the case, it then calculates the damage done by the player (a combination of luck, the amount of NFTs they hold, and powerups they bought). The damage done is subtracted from the hp (new hp is written to the db). Finally, the program checks if the user has won (hp at or under 0). If so, it ends the game and announces the winner.
|
||||
|
||||
However if one player clicks, then another player clicks milliseconds after, in some cases there just hasn't been enough time for the db writes to take place, and so there can be multiple winners. This is **bad**!!!
|
||||
|
||||

|
||||
|
||||
The main problem is, the two functions being run at the same time aren't aware of the existence of the other, and can't communicate to ensure only one winner. I tried a variety of methods, like adding another check to make sure the game didn't end already. None of it worked, unfortunately.
|
||||
|
||||
What did work though, is adding a random delay using `setTimeout` and `Math.random`, if the program thought the user won (`hp <= 0`). After the random delay, a global array variable would be looked at. If the array was empty, then the winner would be announced, and something (doesn't matter what) would be added to the array. I'm not sure why I made it an array, and not an dictionary, but it worked^tm^ (only one game can be run at a time, but if the bot had multiple games running, a dictionary with the keys as game ids set when the winner was found would work better). I probably had a good reason at the time, or at least fooled myself into thinking I did. Anyways, so if there was another winner about to be announced, the program would see the array was not empty, and not announce the extra winner(s).
|
||||
|
||||
Technically, if the random delay was the same or only a few milliseconds different, the global variable could be looked at the same time, and two winners (or more) could still be announced.
|
||||
|
||||
... let's not worry about that
|
||||
|
||||
> (A quick update: in several dozen games, after the fix, the two winner situation never happened again. It wasn't elegant and it was a dumb solution, but it worked! Maybe there was a better solution by fiddling with the database settings, like making database calls queue one at a time?)
|
||||
> **Update, October 2023**: I realize I was being kind of an idiot. In retrospect, what I should've done was have the MongoDB operation be a `replaceOne` that *only* modifies if the damage dealt is under the hp - so it would only be possible for a write to happen for one player even if two click at the same time. Then, I could check the return value of the `replaceOne` (which tells me whether the operation modified documents or not), and discard any fake winners whose clicks did not result in the database being modified. Beware that if you continue reading, you will encounter a very stupid solution to a problem.
|
||||
|
||||
Recently, I've been working on a discord bot game for Beer Goggles NFT on Algorand.
|
||||
|
||||
The specifics aren't too important, but essentially the game works like this: A game is started by an admin, and a secret number of hp is specified. Then, players can click a button, and depending on the amount of NFTs they hold, they will do "damage". All the damage is added up, and the person who crosses the secret number of hp wins. Like a pinata. Or in the case of our bar themed game, a huge opaque mug of beer that is passed around, with the goal being the one to finish the drink.
|
||||
|
||||
Now, onto the more technical details. Whenever a user clicks the button, the callback for the button interaction event is run.
|
||||
|
||||
First, the program reads the database (MongoDB) and sees the current hp left for the current game. If the current hp is less than zero, or a game over flag is set, the user is notified that the game is over, and the click does nothing. If that isn't the case, it then calculates the damage done by the player (a combination of luck, the amount of NFTs they hold, and powerups they bought). The damage done is subtracted from the hp (new hp is written to the db). Finally, the program checks if the user has won (hp at or under 0). If so, it ends the game and announces the winner.
|
||||
|
||||
However if one player clicks, then another player clicks milliseconds after, in some cases there just hasn't been enough time for the db writes to take place, and so there can be multiple winners. This is **bad**!!!
|
||||
|
||||

|
||||
|
||||
The main problem is, the two functions being run at the same time aren't aware of the existence of the other, and can't communicate to ensure only one winner. I tried a variety of methods, like adding another check to make sure the game didn't end already. None of it worked, unfortunately.
|
||||
|
||||
What did work though, is adding a random delay using `setTimeout` and `Math.random`, if the program thought the user won (`hp <= 0`). After the random delay, a global array variable would be looked at. If the array was empty, then the winner would be announced, and something (doesn't matter what) would be added to the array. I'm not sure why I made it an array, and not an dictionary, but it worked^tm^ (only one game can be run at a time, but if the bot had multiple games running, a dictionary with the keys as game ids set when the winner was found would work better). I probably had a good reason at the time, or at least fooled myself into thinking I did. Anyways, so if there was another winner about to be announced, the program would see the array was not empty, and not announce the extra winner(s).
|
||||
|
||||
Technically, if the random delay was the same or only a few milliseconds different, the global variable could be looked at the same time, and two winners (or more) could still be announced.
|
||||
|
||||
... let's not worry about that
|
||||
|
||||
@@ -1,134 +1,159 @@
|
||||
Wikipedia articles. I like them. The "Did you know" and "On this day" sections on the front page are real treasure troves. They have archives too, so you'll never run out of articles to read.
|
||||
|
||||
Here's a very incomplete (and maybe actively updated) list of ones that led to more clicks and were interesting to read:
|
||||
|
||||
- [Second Anglo-Dutch War](https://en.wikipedia.org/wiki/Second_Anglo-Dutch_War)
|
||||
- [Koxinga](https://en.wikipedia.org/wiki/Koxinga), rogue Ming loyalist general who defeated the Dutch and Qing, to rule Taiwan
|
||||
- [Red Turban Rebellions](https://en.wikipedia.org/wiki/Red_Turban_Rebellions) and [Chinese Manichaeism](https://en.wikipedia.org/wiki/Chinese_Manichaeism) connected to each other through Manichaeian influence on the [White Lotus Society](https://en.wikipedia.org/wiki/White_Lotus)
|
||||
- [List of Ethnic Groups in China](https://en.wikipedia.org/wiki/List_of_ethnic_groups_in_China)
|
||||
- [Battle of Dien Bien Phu](https://en.wikipedia.org/wiki/Battle_of_Dien_Bien_Phu), where the Viet Minh kick out the French
|
||||
- [Battle of Saigon (1955)](https://en.wikipedia.org/wiki/Battle_of_Saigon_%281955%29)
|
||||
- [KHTML](https://en.wikipedia.org/wiki/KHTML), made by KDE, which suprisingly is the parent of both Chrome ([Blink](https://en.wikipedia.org/wiki/Blink_%28browser_engine%29)) and Safari ([Webkit](https://en.wikipedia.org/wiki/WebKit))
|
||||
- [Syrian Civil War](https://en.wikipedia.org/wiki/Syrian_civil_war) and it's numerous factions, like the non-secular [Syrian Salvation Government](https://en.wikipedia.org/wiki/Syrian_Salvation_Government) rebels or the Kurdish [Rojava](https://en.wikipedia.org/wiki/Autonomous_Administration_of_North_and_East_Syria) (related: )
|
||||
- [Circassian Genocide](https://en.wikipedia.org/wiki/Circassian_genocide), possibly the biggest genocide of the 19th century
|
||||
- [Basmachi movement](https://en.wikipedia.org/wiki/Basmachi_movement), Central Asian rebellion against Soviet rule, with notable participant [Enver Pasha](https://en.wikipedia.org/wiki/Enver_Pasha), one of the [Three Pashas](https://en.wikipedia.org/wiki/Three_Pashas) who perpetrated the [Armenian Genocide](https://en.wikipedia.org/wiki/Armenian_genocide)
|
||||
- [Saigo Takamori](https://en.wikipedia.org/wiki/Saig%C5%8D_Takamori), [Meiji Restoration](https://en.wikipedia.org/wiki/Meiji_Restoration) and [Satsuma Rebellion](https://en.wikipedia.org/wiki/Satsuma_Rebellion) leader
|
||||
- [Shimabara Rebellion](https://en.wikipedia.org/wiki/Shimabara_Rebellion), Christian rebellion in Japan
|
||||
- [May 68](https://en.wikipedia.org/wiki/May_68), leftist French civil unrest
|
||||
- [Diffie-Hellman key exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)
|
||||
- [Xi'an Incident](https://en.wikipedia.org/wiki/Xi%27an_Incident), where [Chiang Kai-shek](https://en.wikipedia.org/wiki/Chiang_Kai-shek) (leader of the Nationalists) is kidnapped by his generals [Yang Hucheng](https://en.wikipedia.org/wiki/Yang_Hucheng) and [Chang Hsueh-liang](https://en.wikipedia.org/wiki/Chang_Hsueh-liang), and forced to cooperate with the Communists against the invading Japanese
|
||||
- [Abdullah Öcalan](https://en.wikipedia.org/wiki/Abdullah_%C3%96calan), imprisoned [PKK](https://en.wikipedia.org/wiki/Kurdistan_Workers%27_Party) leader
|
||||
- [Oda Nobunaga](https://en.wikipedia.org/wiki/Oda_Nobunaga), extremely notable Japanese warlord, who was killed in the [Honnō-ji Incident](https://en.wikipedia.org/wiki/Honn%C5%8D-ji_Incident)
|
||||
- [Ishiyama Hongan-ji](https://en.wikipedia.org/wiki/Ishiyama_Hongan-ji), former [Jōdo Shinshū](https://en.wikipedia.org/wiki/J%C5%8Ddo_Shinsh%C5%AB) temple/fortress, was burned down and replaced by [Osaka Castle](https://en.wikipedia.org/wiki/Osaka_Castle), and the reason why the city of [Osaka](https://en.wikipedia.org/wiki/Osaka) exists
|
||||
- [Peninsular War](https://en.wikipedia.org/wiki/Peninsular_War), [Napoleon](https://en.wikipedia.org/wiki/Napoleon)'s invasion of Spain and Portugal
|
||||
- [Thomas Cochrane, 10th Earl of Dundonald](https://en.wikipedia.org/wiki/Thomas_Cochrane,_10th_Earl_of_Dundonald), successful British Navy officer accused of stock exchange fraud, later participating in [Liberating Expedition of Peru](https://en.wikipedia.org/wiki/Liberating_Expedition_of_Peru) from the Spanish
|
||||
- [Indonesia invades East Timor](https://en.wikipedia.org/wiki/Indonesian_invasion_of_East_Timor) to overthrow [Fretilin](https://en.wikipedia.org/wiki/Fretilin)
|
||||
- [Special Region of Yogyakarta](https://en.wikipedia.org/wiki/Special_Region_of_Yogyakarta), a region of Indonesia *currently* hereditarily ruled by the [Yogyakarta Sultanate](https://en.wikipedia.org/wiki/Yogyakarta_Sultanate) and the [Duchy of Pakualaman](https://en.wikipedia.org/wiki/Pakualaman)
|
||||
- [Nanboku-chō period](https://en.wikipedia.org/wiki/Nanboku-ch%C5%8D_period), when two opposing Japanese Imperial Courts existed, after the overthrow of the [Kamakura Shogunate](https://en.wikipedia.org/wiki/Kamakura_shogunate) and the failure of the [Kenmu Restoration](https://en.wikipedia.org/wiki/Kenmu_Restoration)
|
||||
- [COINTELPRO](https://en.wikipedia.org/wiki/COINTELPRO), where the FBI unsurprisingly misbehaves
|
||||
- [Transition to the New Order](https://en.wikipedia.org/wiki/Transition_to_the_New_Order), where [Suharto](https://en.wikipedia.org/wiki/Suharto) purges the [Indonesian Communist Party](https://en.wikipedia.org/wiki/Communist_Party_of_Indonesia), and overthrows [Sukarno](https://en.wikipedia.org/wiki/Sukarno)
|
||||
- [Crypto Wars](https://en.wikipedia.org/wiki/Crypto_Wars), where the US Government tries to prevent the public and foreigners from using strong encryption
|
||||
- [The Battle of Blair Mountain](https://en.wikipedia.org/wiki/Battle_of_Blair_Mountain), where striking coal members are bombed
|
||||
- [Haymarket Affair](https://en.wikipedia.org/wiki/Haymarket_affair), where a bomb was thrown at police during a rally supporting the eight-hour work day
|
||||
- [Tigray War](https://en.wikipedia.org/wiki/Tigray_War), a recent rebellion of the Tigrayan Government against the Ethiopian Government
|
||||
- [Timur](https://en.wikipedia.org/wiki/Timur), conquerer and founder of the Timurid Empire, self proclaimed successor of Genghis Khan, and ancestor of the [Mughal Empire](https://en.wikipedia.org/wiki/Mughal_Empire)'s founders
|
||||
- [Year of the Four Emperors](https://en.wikipedia.org/wiki/Year_of_the_Four_Emperors), a period of civil war in the Roman Empire
|
||||
- [Frederick the Great](https://en.wikipedia.org/wiki/Frederick_the_Great), Prussian king, and military general
|
||||
- [Tadeusz Kościuszko](https://en.wikipedia.org/wiki/Tadeusz_Ko%C5%9Bciuszko), leader of the Polish-Lithuanian [Kościuszko Uprising](https://en.wikipedia.org/wiki/Ko%C5%9Bciuszko_Uprising) against Russian rule, and American Revolutionary War hero
|
||||
- [Favelas](https://en.wikipedia.org/wiki/Favela), Brazilian slums, some of which are ruled by cartels or vigilantes
|
||||
- [Princely State](https://en.wikipedia.org/wiki/Princely_state), Indian prince ruled territory under the British
|
||||
- [Annexation of Goa](https://en.wikipedia.org/wiki/Annexation_of_Goa), India invades Portugese ruled Goa
|
||||
- [List of ethnic armed organisations in Myanmar](https://en.wikipedia.org/wiki/List_of_ethnic_armed_organisations_in_Myanmar)
|
||||
- [Marcionism](https://en.wikipedia.org/wiki/Marcionism), early interpretation of Christianity
|
||||
- [Lion-Eating Poet in the Stone Den](https://en.wikipedia.org/wiki/Lion-Eating_Poet_in_the_Stone_Den), shi shi shi shi...
|
||||
- [Fuke-shū](https://en.wikipedia.org/wiki/Fuke-sh%C5%AB), [Shakuhachi](https://en.wikipedia.org/wiki/Shakuhachi) playing, basket wearing, Zen Buddhism sect
|
||||
- [Zen Koans](https://en.wikipedia.org/wiki/Koan), "A monk asked Dongshan Shouchu, 'What is Buddha?' Dongshan said, 'Three pounds of flax.'"
|
||||
- [Shugendō](https://en.wikipedia.org/wiki/Shugend%C5%8D), a religion combining Buddhism, folk religion, and Shinto mountain worship
|
||||
- [Spartacist uprising](https://en.wikipedia.org/wiki/Spartacist_uprising), crushed communist revolt during the early Weimar Republic
|
||||
- [Self-immolation](https://en.wikipedia.org/wiki/Self-immolation)
|
||||
- [Charles Maurice de Talleyrand-Périgord](https://en.wikipedia.org/wiki/Charles_Maurice_de_Talleyrand-P%C3%A9rigord), important French Foreign Minister/diplomat across the French Monarchy, revolution, and Napoleonic period, [Bourbon Restoration](https://en.wikipedia.org/wiki/Bourbon_Restoration_in_France)
|
||||
- [Luigi Lucheni](https://en.wikipedia.org/wiki/Luigi_Lucheni), anarchist assassin using a four-inch file as his weapon
|
||||
- [Hundred Days](https://en.wikipedia.org/wiki/Hundred_Days), Napoleon returns to power, briefly
|
||||
- [Green Corn Rebellion](https://en.wikipedia.org/wiki/Green_Corn_Rebellion), anti-draft rebellion in Oklahoma, USA during WW1
|
||||
- [William Augustus Bowles](https://en.wikipedia.org/wiki/William_Augustus_Bowles), British leader of the Native American State of Muskogee
|
||||
- [Mexican Revolution](https://en.wikipedia.org/wiki/Mexican_Revolution)
|
||||
- [Frozen Conflict](https://en.wikipedia.org/wiki/Frozen_conflict)
|
||||
- [Czechoslovak Legion](https://en.wikipedia.org/wiki/Czechoslovak_Legion), Czechoslovakian volunteer soldiers who found themselves in the middle of the [Russian Civil War](https://en.wikipedia.org/wiki/Russian_Civil_War)
|
||||
- [Yuan Shikai](https://en.wikipedia.org/wiki/Yuan_Shikai), who overthrew the Qing Dynasty, then [tried and failed to proclaim himself emperor](https://en.wikipedia.org/wiki/National_Protection_War)
|
||||
- [Wuchang Uprising](https://en.wikipedia.org/wiki/Wuchang_Uprising)
|
||||
- [Nio](https://en.wikipedia.org/wiki/Nio), guardians at the entrance of many Buddhist temples
|
||||
- [Mount Hiei](https://en.wikipedia.org/wiki/Mount_Hiei), the location of [Enryaku-ji](https://en.wikipedia.org/wiki/Enryaku-ji)
|
||||
- [Mongol Invasions of Japan](https://en.wikipedia.org/wiki/Mongol_invasions_of_Japan)
|
||||
- [Language Isolate](https://en.wikipedia.org/wiki/Language_isolate), languages that aren't classified as part of larger [language families](https://en.wikipedia.org/wiki/Language_family)
|
||||
- [Jiajing Wokou Raids](https://en.wikipedia.org/wiki/Jiajing_wokou_raids), pirates
|
||||
- [Word (computer architecture)](https://en.wikipedia.org/wiki/Word_%28computer_architecture%29)
|
||||
- [Transition from Ming to Qing](https://en.wikipedia.org/wiki/Transition_from_Ming_to_Qing)
|
||||
- [Eighty Years' War](https://en.wikipedia.org/wiki/Eighty_Years%27_War), Dutch independence from Spain
|
||||
- [Abbasid Revolution](https://en.wikipedia.org/wiki/Abbasid_Revolution), the [Umayyad Caliphate](https://en.wikipedia.org/wiki/Umayyad_Caliphate) is overthrown and replaced by the Abbasid Caliphate
|
||||
- [Operation Motorman](https://en.wikipedia.org/wiki/Operation_Motorman), British military operation in Northern Ireland
|
||||
- [Green Armies](https://en.wikipedia.org/wiki/Green_armies) in the Russian Civil War
|
||||
- [Recusants](https://en.wikipedia.org/wiki/Recusancy) are those that did not support the Church of England after the English Reformation
|
||||
- [Terrorism Act 2000](https://en.wikipedia.org/wiki/Terrorism_Act_2000)
|
||||
- [Pontoon bridge](https://en.wikipedia.org/wiki/Pontoon_bridge)
|
||||
- [Francisco Macías Nguema](https://en.wikipedia.org/wiki/Francisco_Mac%C3%ADas_Nguema), completely insane dictator of Equatorial Guinea
|
||||
- [Yazidism](https://en.wikipedia.org/wiki/Yazidism)
|
||||
- [Göbekli Tepe](https://en.wikipedia.org/wiki/G%C3%B6bekli_Tepe), Neolithic archaeological site
|
||||
- [List of unsolved problems in mathematics](https://en.wikipedia.org/wiki/List_of_unsolved_problems_in_mathematics)
|
||||
- [Hartal](https://en.wikipedia.org/wiki/Hartal), Indian strike action
|
||||
- [Achaemenid Empire](https://en.wikipedia.org/wiki/Achaemenid_Empire), very big, pretty cool
|
||||
- [The Camden 28](https://en.wikipedia.org/wiki/The_Camden_28), anti-Vietnam War activists
|
||||
- [Howard Zinn](https://en.wikipedia.org/wiki/Howard_Zinn), controversial historian
|
||||
- [Gnosticism](https://en.wikipedia.org/wiki/Gnosticism) was a set of early Christian beliefs
|
||||
- [TempleOS](https://en.wikipedia.org/wiki/TempleOS)
|
||||
- [Grendel's mother](https://en.wikipedia.org/wiki/Grendel's_mother), an antagonist in the Old English epic poem, Beowulf, who scholars debate whether is a monster or just a female warrior
|
||||
- [Epic of Gilgamesh](https://en.wikipedia.org/wiki/Epic_of_Gilgamesh), Sumerian epic poem
|
||||
- [An Lushan Rebellion](https://en.wikipedia.org/wiki/An_Lushan_Rebellion), An Lushan rebels, greatly weakened the Tang Dynasty
|
||||
- [Bahmani Sultanate](https://en.wikipedia.org/wiki/Bahmani_Sultanate), South Indian empire
|
||||
- [Pagan Empire](https://en.wikipedia.org/wiki/Pagan_Kingdom), the first Burmese kingdom
|
||||
- [Warsaw Uprising](https://en.wikipedia.org/wiki/Warsaw_Uprising)
|
||||
- [Polish-Lithuanian Commonwealth](https://en.wikipedia.org/wiki/Polish%E2%80%93Lithuanian_Commonwealth)
|
||||
- [Atoll](https://en.wikipedia.org/wiki/Atoll)
|
||||
- [Chambre introuvable](https://en.wikipedia.org/wiki/Chambre_introuvable), ultra-royalists Chamber of Deputies elected after the Second Bourbon Restoration
|
||||
- [Fedayeen](https://en.wikipedia.org/wiki/Fedayeen)
|
||||
- [Battle of Nagashino](https://en.wikipedia.org/wiki/Battle_of_Nagashino), where Takeda Katsuyori learns it is not a good idea to cavalry charge into gunfire
|
||||
- [Twenty-Four Generals of Takeda Shingen](https://en.wikipedia.org/wiki/Twenty-Four_Generals_of_Takeda_Shingen), related to the Battle of Nagashino above, but too interesting to leave out
|
||||
- [Battle of Bannockburn](https://en.wikipedia.org/wiki/Battle_of_Bannockburn), decisive Scottish victory in the First War of Scottish Independence
|
||||
- [Three Gorges](https://en.wikipedia.org/wiki/Three_Gorges), are three gorges, in China
|
||||
- [Annexation of Hyderabad](https://en.wikipedia.org/wiki/Annexation_of_Hyderabad)
|
||||
- [Emperor Xuanzong of Tang (9th century)](https://en.wikipedia.org/wiki/Emperor_Xuanzong_of_Tang_%289th_century%29)
|
||||
- [List of coups and coup attempts](https://en.wikipedia.org/wiki/List_of_coups_and_coup_attempts)
|
||||
- [Lazarus Group](https://en.wikipedia.org/wiki/Lazarus_Group), North Korean hackers
|
||||
- [Pasquale Paoli](https://en.wikipedia.org/wiki/Pasquale_Paoli), Corsican nationalist admired by Napoleon
|
||||
- [Doge (title)](https://en.wikipedia.org/wiki/Doge_%28title%29), like a King, but elected
|
||||
- [Frank Serpico](https://en.wikipedia.org/wiki/Frank_Serpico), New York Police Department whistleblower
|
||||
- [Inner Mongolia Incident](https://en.wikipedia.org/wiki/Inner_Mongolia_incident), part of the Cultural Revolution
|
||||
- [Nationalist Party of Puerto_Rico](https://en.wikipedia.org/wiki/Nationalist_Party_of_Puerto_Rico)
|
||||
- [Rotating locomotion in living systems](https://en.wikipedia.org/wiki/Rotating_locomotion_in_living_systems)
|
||||
- [Japanese dialects](https://en.wikipedia.org/wiki/Japanese_dialects)
|
||||
- [Ihor Kolomoyskyi](https://en.wikipedia.org/wiki/Ihor_Kolomoyskyi), Ukrainian oligarch
|
||||
- [Anglophone Crisis](https://en.wikipedia.org/wiki/Anglophone_Crisis), war in Cameroon due to tensions between English speakers and French speakers
|
||||
- [Kivu conflict](https://en.wikipedia.org/wiki/Kivu_conflict)
|
||||
- [History of Somalia](https://en.wikipedia.org/wiki/History_of_Somalia)
|
||||
- [Migration Period](https://en.wikipedia.org/wiki/Migration_Period), which led to the fall of the Western Roman Empire
|
||||
- [Hydrofoil](https://en.wikipedia.org/wiki/Hydrofoil)
|
||||
- [General Sherman (tree)](https://en.wikipedia.org/wiki/General_Sherman_%28tree%29), very big and very old
|
||||
- [Simón Bolívar](https://en.wikipedia.org/wiki/Sim%C3%B3n_Bol%C3%ADvar), South American revolutionary hero
|
||||
- [Battle of Dibrivka](https://en.wikipedia.org/wiki/Battle_of_Dibrivka)
|
||||
- [Battle of the Teutoburg Forest](https://en.wikipedia.org/wiki/Battle_of_the_Teutoburg_Forest)
|
||||
- [Intentional Community](https://en.wikipedia.org/wiki/Intentional_community)
|
||||
- [Jellyfish](https://en.wikipedia.org/wiki/Jellyfish) are apparently "the informal common names given to the medusa-phase of certain gelatinous members of the subphylum Medusozoa"
|
||||
- [Sinecure](https://en.wikipedia.org/wiki/Sinecure), get paid to do nothing
|
||||
- [Yelü Dashi](https://en.wikipedia.org/wiki/Yel%C3%BC_Dashi), founder of the Western Liao dynasty
|
||||
- [List of Unicode characters](https://en.wikipedia.org/wiki/List_of_Unicode_characters)
|
||||
- [Operation Cyclone](https://en.m.wikipedia.org/wiki/Operation_Cyclone), where the CIA funds Islamist groups to fight against the communist Afghan government
|
||||
- [Witold Pilecki](https://en.wikipedia.org/wiki/Witold_Pilecki), brave Polish soldier who intentionally got sent to Auschwitz to spy, *then* voluntarily returned to Communist Poland, again to spy, and was executed
|
||||
- [Ascall mac Ragnaill](https://en.wikipedia.org/wiki/Ascall_mac_Ragnaill), Last Norse-Gaelic King of Dublin
|
||||
- [Iodine](https://en.wikipedia.org/wiki/Iodine), the element
|
||||
- [Riot control](https://en.wikipedia.org/wiki/Riot_control)
|
||||
- [Feoffment](https://en.wikipedia.org/wiki/Feoffment), land for loyalty
|
||||
- [Kent State shootings](https://en.wikipedia.org/wiki/Kent_State_shootings), US National Guard shoots students protesting against US involvement in Cambodia during the Vietnam War
|
||||
- [Mountain men](https://en.wikipedia.org/wiki/Mountain_man)
|
||||
- [1728 Musin Rebellion](https://en.wikipedia.org/wiki/1728_Musin_Rebellion) against the Korean Joseon Dynasty
|
||||
- [Kurt Gödel](https://en.wikipedia.org/wiki/Kurt_G%C3%B6del), mathematician
|
||||
- [Joe Hill](https://en.wikipedia.org/wiki/Joe_Hill_%28activist%29)
|
||||
- [Dual_EC_DRBG](https://en.wikipedia.org/wiki/Dual_EC_DRBG), a (probably) NSA backdoored random number generator
|
||||
Wikipedia articles. I like them. The "Did you know" and "On this day" sections on the front page are real treasure troves. They have archives too, so you'll never run out of articles to read.
|
||||
|
||||
Here's a very incomplete (and maybe actively updated) list of ones that led to more clicks and were interesting to read:
|
||||
|
||||
- [Second Anglo-Dutch War](https://en.wikipedia.org/wiki/Second_Anglo-Dutch_War)
|
||||
- [Koxinga](https://en.wikipedia.org/wiki/Koxinga), rogue Ming loyalist general who defeated the Dutch and Qing, to rule Taiwan
|
||||
- [Red Turban Rebellions](https://en.wikipedia.org/wiki/Red_Turban_Rebellions) and [Chinese Manichaeism](https://en.wikipedia.org/wiki/Chinese_Manichaeism) connected to each other through Manichaeian influence on the [White Lotus Society](https://en.wikipedia.org/wiki/White_Lotus)
|
||||
- [List of Ethnic Groups in China](https://en.wikipedia.org/wiki/List_of_ethnic_groups_in_China)
|
||||
- [Battle of Dien Bien Phu](https://en.wikipedia.org/wiki/Battle_of_Dien_Bien_Phu), where the Viet Minh kick out the French
|
||||
- [Battle of Saigon (1955)](https://en.wikipedia.org/wiki/Battle_of_Saigon_%281955%29)
|
||||
- [KHTML](https://en.wikipedia.org/wiki/KHTML), made by KDE, which suprisingly is the parent of both Chrome ([Blink](https://en.wikipedia.org/wiki/Blink_%28browser_engine%29)) and Safari ([Webkit](https://en.wikipedia.org/wiki/WebKit))
|
||||
- [Syrian Civil War](https://en.wikipedia.org/wiki/Syrian_civil_war) and it's numerous factions, like the non-secular [Syrian Salvation Government](https://en.wikipedia.org/wiki/Syrian_Salvation_Government) rebels or the Kurdish [Rojava](https://en.wikipedia.org/wiki/Autonomous_Administration_of_North_and_East_Syria) (related: )
|
||||
- [Circassian Genocide](https://en.wikipedia.org/wiki/Circassian_genocide), possibly the biggest genocide of the 19th century
|
||||
- [Basmachi movement](https://en.wikipedia.org/wiki/Basmachi_movement), Central Asian rebellion against Soviet rule, with notable participant [Enver Pasha](https://en.wikipedia.org/wiki/Enver_Pasha), one of the [Three Pashas](https://en.wikipedia.org/wiki/Three_Pashas) who perpetrated the [Armenian Genocide](https://en.wikipedia.org/wiki/Armenian_genocide)
|
||||
- [Saigo Takamori](https://en.wikipedia.org/wiki/Saig%C5%8D_Takamori), [Meiji Restoration](https://en.wikipedia.org/wiki/Meiji_Restoration) and [Satsuma Rebellion](https://en.wikipedia.org/wiki/Satsuma_Rebellion) leader
|
||||
- [Shimabara Rebellion](https://en.wikipedia.org/wiki/Shimabara_Rebellion), Christian rebellion in Japan
|
||||
- [May 68](https://en.wikipedia.org/wiki/May_68), leftist French civil unrest
|
||||
- [Diffie-Hellman key exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)
|
||||
- [Xi'an Incident](https://en.wikipedia.org/wiki/Xi%27an_Incident), where [Chiang Kai-shek](https://en.wikipedia.org/wiki/Chiang_Kai-shek) (leader of the Nationalists) is kidnapped by his generals [Yang Hucheng](https://en.wikipedia.org/wiki/Yang_Hucheng) and [Chang Hsueh-liang](https://en.wikipedia.org/wiki/Chang_Hsueh-liang), and forced to cooperate with the Communists against the invading Japanese
|
||||
- [Abdullah Öcalan](https://en.wikipedia.org/wiki/Abdullah_%C3%96calan), imprisoned [PKK](https://en.wikipedia.org/wiki/Kurdistan_Workers%27_Party) leader
|
||||
- [Oda Nobunaga](https://en.wikipedia.org/wiki/Oda_Nobunaga), extremely notable Japanese warlord, who was killed in the [Honnō-ji Incident](https://en.wikipedia.org/wiki/Honn%C5%8D-ji_Incident)
|
||||
- [Ishiyama Hongan-ji](https://en.wikipedia.org/wiki/Ishiyama_Hongan-ji), former [Jōdo Shinshū](https://en.wikipedia.org/wiki/J%C5%8Ddo_Shinsh%C5%AB) temple/fortress, was burned down and replaced by [Osaka Castle](https://en.wikipedia.org/wiki/Osaka_Castle), and the reason why the city of [Osaka](https://en.wikipedia.org/wiki/Osaka) exists
|
||||
- [Peninsular War](https://en.wikipedia.org/wiki/Peninsular_War), [Napoleon](https://en.wikipedia.org/wiki/Napoleon)'s invasion of Spain and Portugal
|
||||
- [Thomas Cochrane, 10th Earl of Dundonald](https://en.wikipedia.org/wiki/Thomas_Cochrane,_10th_Earl_of_Dundonald), successful British Navy officer accused of stock exchange fraud, later participating in [Liberating Expedition of Peru](https://en.wikipedia.org/wiki/Liberating_Expedition_of_Peru) from the Spanish
|
||||
- [Indonesia invades East Timor](https://en.wikipedia.org/wiki/Indonesian_invasion_of_East_Timor) to overthrow [Fretilin](https://en.wikipedia.org/wiki/Fretilin)
|
||||
- [Special Region of Yogyakarta](https://en.wikipedia.org/wiki/Special_Region_of_Yogyakarta), a region of Indonesia *currently* hereditarily ruled by the [Yogyakarta Sultanate](https://en.wikipedia.org/wiki/Yogyakarta_Sultanate) and the [Duchy of Pakualaman](https://en.wikipedia.org/wiki/Pakualaman)
|
||||
- [Nanboku-chō period](https://en.wikipedia.org/wiki/Nanboku-ch%C5%8D_period), when two opposing Japanese Imperial Courts existed, after the overthrow of the [Kamakura Shogunate](https://en.wikipedia.org/wiki/Kamakura_shogunate) and the failure of the [Kenmu Restoration](https://en.wikipedia.org/wiki/Kenmu_Restoration)
|
||||
- [COINTELPRO](https://en.wikipedia.org/wiki/COINTELPRO), where the FBI unsurprisingly misbehaves
|
||||
- [Transition to the New Order](https://en.wikipedia.org/wiki/Transition_to_the_New_Order), where [Suharto](https://en.wikipedia.org/wiki/Suharto) purges the [Indonesian Communist Party](https://en.wikipedia.org/wiki/Communist_Party_of_Indonesia), and overthrows [Sukarno](https://en.wikipedia.org/wiki/Sukarno)
|
||||
- [Crypto Wars](https://en.wikipedia.org/wiki/Crypto_Wars), where the US Government tries to prevent the public and foreigners from using strong encryption
|
||||
- [The Battle of Blair Mountain](https://en.wikipedia.org/wiki/Battle_of_Blair_Mountain), where striking coal members are bombed
|
||||
- [Haymarket Affair](https://en.wikipedia.org/wiki/Haymarket_affair), where a bomb was thrown at police during a rally supporting the eight-hour work day
|
||||
- [Tigray War](https://en.wikipedia.org/wiki/Tigray_War), a recent rebellion of the Tigrayan Government against the Ethiopian Government
|
||||
- [Timur](https://en.wikipedia.org/wiki/Timur), conquerer and founder of the Timurid Empire, self proclaimed successor of Genghis Khan, and ancestor of the [Mughal Empire](https://en.wikipedia.org/wiki/Mughal_Empire)'s founders
|
||||
- [Year of the Four Emperors](https://en.wikipedia.org/wiki/Year_of_the_Four_Emperors), a period of civil war in the Roman Empire
|
||||
- [Frederick the Great](https://en.wikipedia.org/wiki/Frederick_the_Great), Prussian king, and military general
|
||||
- [Tadeusz Kościuszko](https://en.wikipedia.org/wiki/Tadeusz_Ko%C5%9Bciuszko), leader of the Polish-Lithuanian [Kościuszko Uprising](https://en.wikipedia.org/wiki/Ko%C5%9Bciuszko_Uprising) against Russian rule, and American Revolutionary War hero
|
||||
- [Favelas](https://en.wikipedia.org/wiki/Favela), Brazilian slums, some of which are ruled by cartels or vigilantes
|
||||
- [Princely State](https://en.wikipedia.org/wiki/Princely_state), Indian prince ruled territory under the British
|
||||
- [Annexation of Goa](https://en.wikipedia.org/wiki/Annexation_of_Goa), India invades Portugese ruled Goa
|
||||
- [List of ethnic armed organisations in Myanmar](https://en.wikipedia.org/wiki/List_of_ethnic_armed_organisations_in_Myanmar)
|
||||
- [Marcionism](https://en.wikipedia.org/wiki/Marcionism), early interpretation of Christianity
|
||||
- [Lion-Eating Poet in the Stone Den](https://en.wikipedia.org/wiki/Lion-Eating_Poet_in_the_Stone_Den), shi shi shi shi...
|
||||
- [Fuke-shū](https://en.wikipedia.org/wiki/Fuke-sh%C5%AB), [Shakuhachi](https://en.wikipedia.org/wiki/Shakuhachi) playing, basket wearing, Zen Buddhism sect
|
||||
- [Zen Koans](https://en.wikipedia.org/wiki/Koan), "A monk asked Dongshan Shouchu, 'What is Buddha?' Dongshan said, 'Three pounds of flax.'"
|
||||
- [Shugendō](https://en.wikipedia.org/wiki/Shugend%C5%8D), a religion combining Buddhism, folk religion, and Shinto mountain worship
|
||||
- [Spartacist uprising](https://en.wikipedia.org/wiki/Spartacist_uprising), crushed communist revolt during the early Weimar Republic
|
||||
- [Self-immolation](https://en.wikipedia.org/wiki/Self-immolation)
|
||||
- [Charles Maurice de Talleyrand-Périgord](https://en.wikipedia.org/wiki/Charles_Maurice_de_Talleyrand-P%C3%A9rigord), important French Foreign Minister/diplomat across the French Monarchy, revolution, and Napoleonic period, [Bourbon Restoration](https://en.wikipedia.org/wiki/Bourbon_Restoration_in_France)
|
||||
- [Luigi Lucheni](https://en.wikipedia.org/wiki/Luigi_Lucheni), anarchist assassin using a four-inch file as his weapon
|
||||
- [Hundred Days](https://en.wikipedia.org/wiki/Hundred_Days), Napoleon returns to power, briefly
|
||||
- [Green Corn Rebellion](https://en.wikipedia.org/wiki/Green_Corn_Rebellion), anti-draft rebellion in Oklahoma, USA during WW1
|
||||
- [William Augustus Bowles](https://en.wikipedia.org/wiki/William_Augustus_Bowles), British leader of the Native American State of Muskogee
|
||||
- [Mexican Revolution](https://en.wikipedia.org/wiki/Mexican_Revolution)
|
||||
- [Frozen Conflict](https://en.wikipedia.org/wiki/Frozen_conflict)
|
||||
- [Czechoslovak Legion](https://en.wikipedia.org/wiki/Czechoslovak_Legion), Czechoslovakian volunteer soldiers who found themselves in the middle of the [Russian Civil War](https://en.wikipedia.org/wiki/Russian_Civil_War)
|
||||
- [Yuan Shikai](https://en.wikipedia.org/wiki/Yuan_Shikai), who overthrew the Qing Dynasty, then [tried and failed to proclaim himself emperor](https://en.wikipedia.org/wiki/National_Protection_War)
|
||||
- [Wuchang Uprising](https://en.wikipedia.org/wiki/Wuchang_Uprising)
|
||||
- [Nio](https://en.wikipedia.org/wiki/Nio), guardians at the entrance of many Buddhist temples
|
||||
- [Mount Hiei](https://en.wikipedia.org/wiki/Mount_Hiei), the location of [Enryaku-ji](https://en.wikipedia.org/wiki/Enryaku-ji)
|
||||
- [Mongol Invasions of Japan](https://en.wikipedia.org/wiki/Mongol_invasions_of_Japan)
|
||||
- [Language Isolate](https://en.wikipedia.org/wiki/Language_isolate), languages that aren't classified as part of larger [language families](https://en.wikipedia.org/wiki/Language_family)
|
||||
- [Jiajing Wokou Raids](https://en.wikipedia.org/wiki/Jiajing_wokou_raids), pirates
|
||||
- [Word (computer architecture)](https://en.wikipedia.org/wiki/Word_%28computer_architecture%29)
|
||||
- [Transition from Ming to Qing](https://en.wikipedia.org/wiki/Transition_from_Ming_to_Qing)
|
||||
- [Eighty Years' War](https://en.wikipedia.org/wiki/Eighty_Years%27_War), Dutch independence from Spain
|
||||
- [Abbasid Revolution](https://en.wikipedia.org/wiki/Abbasid_Revolution), the [Umayyad Caliphate](https://en.wikipedia.org/wiki/Umayyad_Caliphate) is overthrown and replaced by the Abbasid Caliphate
|
||||
- [Operation Motorman](https://en.wikipedia.org/wiki/Operation_Motorman), British military operation in Northern Ireland
|
||||
- [Green Armies](https://en.wikipedia.org/wiki/Green_armies) in the Russian Civil War
|
||||
- [Recusants](https://en.wikipedia.org/wiki/Recusancy) are those that did not support the Church of England after the English Reformation
|
||||
- [Terrorism Act 2000](https://en.wikipedia.org/wiki/Terrorism_Act_2000)
|
||||
- [Pontoon bridge](https://en.wikipedia.org/wiki/Pontoon_bridge)
|
||||
- [Francisco Macías Nguema](https://en.wikipedia.org/wiki/Francisco_Mac%C3%ADas_Nguema), completely insane dictator of Equatorial Guinea
|
||||
- [Yazidism](https://en.wikipedia.org/wiki/Yazidism)
|
||||
- [Göbekli Tepe](https://en.wikipedia.org/wiki/G%C3%B6bekli_Tepe), Neolithic archaeological site
|
||||
- [List of unsolved problems in mathematics](https://en.wikipedia.org/wiki/List_of_unsolved_problems_in_mathematics)
|
||||
- [Hartal](https://en.wikipedia.org/wiki/Hartal), Indian strike action
|
||||
- [Achaemenid Empire](https://en.wikipedia.org/wiki/Achaemenid_Empire), very big, pretty cool
|
||||
- [The Camden 28](https://en.wikipedia.org/wiki/The_Camden_28), anti-Vietnam War activists
|
||||
- [Howard Zinn](https://en.wikipedia.org/wiki/Howard_Zinn), controversial historian
|
||||
- [Gnosticism](https://en.wikipedia.org/wiki/Gnosticism) was a set of early Christian beliefs
|
||||
- [TempleOS](https://en.wikipedia.org/wiki/TempleOS)
|
||||
- [Grendel's mother](https://en.wikipedia.org/wiki/Grendel's_mother), an antagonist in the Old English epic poem, Beowulf, who scholars debate whether is a monster or just a female warrior
|
||||
- [Epic of Gilgamesh](https://en.wikipedia.org/wiki/Epic_of_Gilgamesh), Sumerian epic poem
|
||||
- [An Lushan Rebellion](https://en.wikipedia.org/wiki/An_Lushan_Rebellion), An Lushan rebels, greatly weakened the Tang Dynasty
|
||||
- [Bahmani Sultanate](https://en.wikipedia.org/wiki/Bahmani_Sultanate), South Indian empire
|
||||
- [Pagan Empire](https://en.wikipedia.org/wiki/Pagan_Kingdom), the first Burmese kingdom
|
||||
- [Warsaw Uprising](https://en.wikipedia.org/wiki/Warsaw_Uprising)
|
||||
- [Polish-Lithuanian Commonwealth](https://en.wikipedia.org/wiki/Polish%E2%80%93Lithuanian_Commonwealth)
|
||||
- [Atoll](https://en.wikipedia.org/wiki/Atoll)
|
||||
- [Chambre introuvable](https://en.wikipedia.org/wiki/Chambre_introuvable), ultra-royalists Chamber of Deputies elected after the Second Bourbon Restoration
|
||||
- [Fedayeen](https://en.wikipedia.org/wiki/Fedayeen)
|
||||
- [Battle of Nagashino](https://en.wikipedia.org/wiki/Battle_of_Nagashino), where Takeda Katsuyori learns it is not a good idea to cavalry charge into gunfire
|
||||
- [Twenty-Four Generals of Takeda Shingen](https://en.wikipedia.org/wiki/Twenty-Four_Generals_of_Takeda_Shingen), related to the Battle of Nagashino above, but too interesting to leave out
|
||||
- [Battle of Bannockburn](https://en.wikipedia.org/wiki/Battle_of_Bannockburn), decisive Scottish victory in the First War of Scottish Independence
|
||||
- [Three Gorges](https://en.wikipedia.org/wiki/Three_Gorges), are three gorges, in China
|
||||
- [Annexation of Hyderabad](https://en.wikipedia.org/wiki/Annexation_of_Hyderabad)
|
||||
- [Emperor Xuanzong of Tang (9th century)](https://en.wikipedia.org/wiki/Emperor_Xuanzong_of_Tang_%289th_century%29)
|
||||
- [List of coups and coup attempts](https://en.wikipedia.org/wiki/List_of_coups_and_coup_attempts)
|
||||
- [Lazarus Group](https://en.wikipedia.org/wiki/Lazarus_Group), North Korean hackers
|
||||
- [Pasquale Paoli](https://en.wikipedia.org/wiki/Pasquale_Paoli), Corsican nationalist admired by Napoleon
|
||||
- [Doge (title)](https://en.wikipedia.org/wiki/Doge_%28title%29), like a King, but elected
|
||||
- [Frank Serpico](https://en.wikipedia.org/wiki/Frank_Serpico), New York Police Department whistleblower
|
||||
- [Inner Mongolia Incident](https://en.wikipedia.org/wiki/Inner_Mongolia_incident), part of the Cultural Revolution
|
||||
- [Nationalist Party of Puerto_Rico](https://en.wikipedia.org/wiki/Nationalist_Party_of_Puerto_Rico)
|
||||
- [Rotating locomotion in living systems](https://en.wikipedia.org/wiki/Rotating_locomotion_in_living_systems)
|
||||
- [Japanese dialects](https://en.wikipedia.org/wiki/Japanese_dialects)
|
||||
- [Ihor Kolomoyskyi](https://en.wikipedia.org/wiki/Ihor_Kolomoyskyi), Ukrainian oligarch
|
||||
- [Anglophone Crisis](https://en.wikipedia.org/wiki/Anglophone_Crisis), war in Cameroon due to tensions between English speakers and French speakers
|
||||
- [Kivu conflict](https://en.wikipedia.org/wiki/Kivu_conflict)
|
||||
- [History of Somalia](https://en.wikipedia.org/wiki/History_of_Somalia)
|
||||
- [Migration Period](https://en.wikipedia.org/wiki/Migration_Period), which led to the fall of the Western Roman Empire
|
||||
- [Hydrofoil](https://en.wikipedia.org/wiki/Hydrofoil)
|
||||
- [General Sherman (tree)](https://en.wikipedia.org/wiki/General_Sherman_%28tree%29), very big and very old
|
||||
- [Simón Bolívar](https://en.wikipedia.org/wiki/Sim%C3%B3n_Bol%C3%ADvar), South American revolutionary hero
|
||||
- [Battle of Dibrivka](https://en.wikipedia.org/wiki/Battle_of_Dibrivka)
|
||||
- [Battle of the Teutoburg Forest](https://en.wikipedia.org/wiki/Battle_of_the_Teutoburg_Forest)
|
||||
- [Intentional Community](https://en.wikipedia.org/wiki/Intentional_community)
|
||||
- [Jellyfish](https://en.wikipedia.org/wiki/Jellyfish) are apparently "the informal common names given to the medusa-phase of certain gelatinous members of the subphylum Medusozoa"
|
||||
- [Sinecure](https://en.wikipedia.org/wiki/Sinecure), get paid to do nothing
|
||||
- [Yelü Dashi](https://en.wikipedia.org/wiki/Yel%C3%BC_Dashi), founder of the Western Liao dynasty
|
||||
- [List of Unicode characters](https://en.wikipedia.org/wiki/List_of_Unicode_characters)
|
||||
- [Operation Cyclone](https://en.m.wikipedia.org/wiki/Operation_Cyclone), where the CIA funds Islamist groups to fight against the communist Afghan government
|
||||
- [Witold Pilecki](https://en.wikipedia.org/wiki/Witold_Pilecki), brave Polish soldier who intentionally got sent to Auschwitz to spy, *then* voluntarily returned to Communist Poland, again to spy, and was executed
|
||||
- [Ascall mac Ragnaill](https://en.wikipedia.org/wiki/Ascall_mac_Ragnaill), Last Norse-Gaelic King of Dublin
|
||||
- [Iodine](https://en.wikipedia.org/wiki/Iodine), the element
|
||||
- [Riot control](https://en.wikipedia.org/wiki/Riot_control)
|
||||
- [Feoffment](https://en.wikipedia.org/wiki/Feoffment), land for loyalty
|
||||
- [Kent State shootings](https://en.wikipedia.org/wiki/Kent_State_shootings), US National Guard shoots students protesting against US involvement in Cambodia during the Vietnam War
|
||||
- [Mountain men](https://en.wikipedia.org/wiki/Mountain_man)
|
||||
- [1728 Musin Rebellion](https://en.wikipedia.org/wiki/1728_Musin_Rebellion) against the Korean Joseon Dynasty
|
||||
- [Kurt Gödel](https://en.wikipedia.org/wiki/Kurt_G%C3%B6del), mathematician
|
||||
- [Joe Hill](https://en.wikipedia.org/wiki/Joe_Hill_%28activist%29)
|
||||
- [Dual_EC_DRBG](https://en.wikipedia.org/wiki/Dual_EC_DRBG), a (probably) NSA backdoored random number generator
|
||||
- [English-based creole languages](https://en.wikipedia.org/wiki/English-based_creole_languages)
|
||||
- [Austro-Hungarian concession of Tianjin](https://en.wikipedia.org/wiki/Austro-Hungarian_concession_of_Tianjin)
|
||||
- [Steve Mann (inventor)](https://en.wikipedia.org/wiki/Steve_Mann_%28inventor%29), inventor of wearable computing technology
|
||||
- [Kronstadt rebellion](https://en.wikipedia.org/wiki/Kronstadt_rebellion), revolt against the Bolsheviks by Soviet soldiers
|
||||
- [Great Purge](https://en.wikipedia.org/wiki/Great_Purge), Stalin purges a lot of people
|
||||
- [Iranian Revolution](https://en.wikipedia.org/wiki/Iranian_Revolution)
|
||||
- [Cultural Revolution](https://en.wikipedia.org/wiki/Cultural_Revolution), which didn't turn out very well at all
|
||||
- [National Treasure (Japan)](https://en.wikipedia.org/wiki/National_Treasure_%28Japan%29)
|
||||
- [Protozoa](https://en.wikipedia.org/wiki/Protozoa)
|
||||
- [Akira Kurosawa](https://en.wikipedia.org/wiki/Akira_Kurosawa), filmmaker
|
||||
- [Isle of Man](https://en.wikipedia.org/wiki/Isle_of_Man)
|
||||
- [Fantastic War](https://en.wikipedia.org/wiki/Fantastic_War), fought between Spain and Portugal as part of the [Seven Years' War](https://en.wikipedia.org/wiki/Seven_Years%27_War). Was not fantastic for Spain, since they lost
|
||||
- [Nikoli](https://en.wikipedia.org/wiki/Nikoli_%28publisher%29), publisher of puzzle gmaes like Sudoku
|
||||
- [Sikkim](https://en.wikipedia.org/wiki/Sikkim)
|
||||
- [Subutai](https://en.wikipedia.org/wiki/Subutai), Mongol general who invaded Hungary
|
||||
- [Free speech fights](https://en.wikipedia.org/wiki/Free_speech_fights), usually suppression of labour issue related speech
|
||||
- [Sesshū Tōyō](https://en.wikipedia.org/wiki/Sessh%C5%AB_T%C5%8Dy%C5%8D), painter
|
||||
- [Java War (1741–1743)](https://en.wikipedia.org/wiki/Java_War_%281741%E2%80%931743%29)
|
||||
- [Tuareg people](https://en.wikipedia.org/wiki/Tuareg_people)
|
||||
- [Amnesty International](https://en.wikipedia.org/wiki/Amnesty_International)
|
||||
- [Julian Assange](https://en.wikipedia.org/wiki/Julian_Assange)
|
||||
- [Bukharian (Judeo-Tajik dialect)](https://en.wikipedia.org/wiki/Bukharian_%28Judeo-Tajik_dialect%29)
|
||||
- [Qt (software)](https://en.wikipedia.org/wiki/Qt_%28software%29), for developing GUIs
|
||||
- [Sailfish OS](https://en.wikipedia.org/wiki/Sailfish_OS)
|
||||
- [SerenityOS](https://en.wikipedia.org/wiki/SerenityOS)
|
||||
|
||||
Reference in New Issue
Block a user