Drop #626 (2025-03-24): Monday Morning Grab Bag
Djot; Bean CMS; The GitHub ⭐️ Clean Slate Protocol
(Two missed Drops due to a week of brutal and Constitution-destroying EOs, the launch of a 47 Watch podcast, work on a — for now — seekrit datavis collaboration with an amazing human, and the last couple days before shunting #4 back up to UMaine.)
Technically, this is only a grab bag due to the last section. The first two are joined at the hip, and now I have a fairly strong urge to build an R package for the resource in the first section.
TL;DR
(This is an AI-generated summary of today’s Drop using Ollama + llama 3.2 and a custom prompt.)
Djot is a markup language that builds on CommonMark’s foundation with improved syntax and parsing, offering features like definition lists, footnotes, tables, and arbitrary attributes while parsing in linear time without backtracking (https://djot.net).
Bean CMS is a minimal content management system built with redbean that stores posts, users, and session information in local SQLite files, providing a spartan but functional interface for content management (https://github.com/kevinfiol/beancms).
The GitHub Star Clean Slate Protocol suggests removing all GitHub stars to avoid spammy solicitations, using a simple one-liner provided in the last section.
Djot
Djot (GH) is a markup language that tries to do what Markdown never quite pulled off: be simple and precise. It builds on CommonMark’s foundation, but smooths out the edges—both in terms of syntax and the way it gets parsed. Djot grew out of John MacFarlane’s essay Beyond Markdown, and it reads like a direct response to the awkward corners and performance issues that have haunted Markdown from the start.
Right out of the box, Djot supports some things you’d expect from a grown-up markup language in 2025, like:
definition lists
footnotes
tables
extra inline formatting (insertions, deletions, highlights, superscript, subscript)
math support
smart punctuation
block and inline containers
arbitrary attributes on anything
These are things Markdown always made you hack around or just skip entirely.
Djot’s design is built around a few core ideas that fix longstanding problems with Markdown parsing:
it parses in linear time, which means it doesn’t waste cycles trying to guess context or backtrack like CommonMark sometimes does
it also parses inline elements locally, so references and links don’t depend on random labels defined somewhere else. This makes Djot friendlier to syntax highlighters and editors that don’t want to parse an entire file just to figure out how to color one line
it draws a hard line: _ means emphasis, * means strong. No more “is this italic or bold or both?” ambiguity.
it is consistent: syntax behaves the same inside list items, block quotes, and anywhere else—no special rules tucked away in the corners
everything can have attributes: ou can attach metadata to any element without needing special syntax extensions
The format also tightens up a few places where Markdown has always been loose or frustrating:
you can’t accidentally break paragraphs with block elements
lists behave more predictably—they’re driven by indentation, not whitespace guesswork
headings can span multiple lines without special rules
raw HTML is opt-in, not just pass-through
reference links are parsed locally and are case-sensitive, not scattered and vague
If you want to try Djot, there’s a JavaScript implementation ready to go:
$ npm install -g @djot/djot$ djot --help
You can also find implementations in Lua, Rust, Go, Haskell, even Prolog—because of course someone did it in Prolog.
If you already use pandoc, Djot fits right in. Here’s how to convert a Markdown file to Djot:
$ pandoc mydoc.md -f gfm -t json | djot -f pandoc -t djot > mydoc.dj
And here’s going from Djot to a Word doc:
$ djot -t pandoc mydoc.dj | pandoc -f json -s -t docx -o mydoc.docx
Djot files typically use the .dj extension.
The syntax isn’t locked down yet — there may be small changes as it evolves — but the core is stable, and the reference implementation in JavaScript is complete and usable right now.
There’s tons more info at the README; there are Go, Rust, TypeScript and more implementations; and you can quickly get a feel for it by using the playground and keeping the docs handy.
Bean CMS
We introduced Djot in the first section to set up this section.
Bean CMS is a micro-CMS built with redbean.
A quick refresher on redbean: it is an open-source, single-file web server that runs natively on six operating systems across both AMD64 and ARM64 architectures. It’s written in ANSI C and embeds Lua 5.4, MbedTLS, and SQLite into a single executable.
There is not much to “tell” about Bean CMS — it is a bare bones content management system. Posts, users, and session information is stored in local SQLite files, and images used in posts are referenced from a local directory.
The binary is meant to be placed in the top-level directory where all the databases and content will be stored, so you should do sometihing like:
$ cd /some/path/where/bean/content/goes$ ./beancms -D ./ -p PORT -b 127.0.0.1
Config options are minimal but sufficient:
Code block rendering is decent:
Post editing is spartan but does what you need it to do:
And, there’s even an admin panel (at /admin):
It’s built on fullmoon — a redbean-based web framework — (which we’ll cover in some future Drop) with very readable Lua and templates files.
I fronted an instance of it with a Caddy reverse proxy, and you can [re]read the Djot section over there.
It appears to have been born in early December last year, and the author — Kevin Fiol — started using signed commits towards the end of December (which are still spiffy, but with all the GitHub account takeovers, I’m not sure I trust anything signed-but-still-hosted-on-GitHub anymore).
Kevin also has his own Bean ’splainer up.
This has tons of potential to be a personal note-taking system, especially since it’s all backed by SQLite.
I’ll definitely be keeping an eye on this one.
The GitHub ⭐️ Clean Slate Protocol
I whined on the socials about yet-another skeezy, spammy “Hey! I saw you [starred XYZ repo|were fond of XYZ] and wanted to let you know about this other super cool ZYZ.” unsolicited email.
First off: DO NOT DO THIS NO MATTER HOW COOL YOU THINK YOUR PROJECT IS.
At least do not do it to me, as you will be marked as a spammer, blocked permanently wherever I can, shunned in person, and be forced to spoon feed ketchup to Donald Trump for eternity when you leave this mortal coil.
Anyway.
It got a few likes, and friend-of-the-Drop Adam S. (I did not ask permission to use Adam’s handle or full name) remarked about github-unstar a day or so later. It’s a neat JS-based CLI tool to nuke all your GitHub stars.
It honestly never occurred to me to unstar everything I had daftly starred. Adam: you are a genius!
But, that tool did not work for me because it did not handle the edge case where your record of a GitHub star event has rotted due to the owner of the repo either no longer having a GitHub account, or having deleted said repo. (I keep thinking there’s a way to take malicious advantage of this condition, but it’s so niche that I will likely not spend much time noodling it.) With all their resources you’d think Microsoft would have some process to help you deal with GH star link rot, but they are woefully incompetent and lack attention to detail in so many areas, that I am not even remotely surprised they do not.
Where there’s a will, there’s a Bash script, and we don’t need the bloat of an NPM package anyway if we have GitHub’s gh utility handy (which I do since I still have to use GitHub for $WORK).
You can easily get info about all your starred repos via:
$ gh api --paginate user/starred'
That will DoS your terminal, so perhaps you just want to see the URLs:
$ gh api --paginate user/starred --jq '.[].html_url'
Ideally, you’d back up all your stars (to put into some other system, like Raindrop.io) first, but you can go all Iron Man and just destroy everything:
$ gh api --paginate user/starred --jq '.[].full_name' | xargs -I{} sh -c 'echo "💥 {}"; gh api -X DELETE user/starred/{}; sleep 0.5'
Bye. Bye. Spammers.
FIN
Remember, you can follow and interact with the full text of The Daily Drop’s free posts on:
🐘 Mastodon via @dailydrop.hrbrmstr.dev@dailydrop.hrbrmstr.dev
🦋 Bluesky via https://bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy
Also, refer to:
to see how to access a regularly updated database of all the Drops with extracted links, and full-text search capability. ☮️