DEV Community

chovy
chovy

Posted on Originally published at dev.profullstack.com

readm3 can edit now, and it speaks Reddit

readm3 can edit now, and it speaks Reddit

readm3 started as a markdown reader for the terminal. File browser on the left,
rendered document on the right. Version 0.3.0 adds the obvious missing half: you
can change the file you are looking at.

Press e, type, press esc. The preview has already re-rendered by the time you
get back to it, because both modes read the same buffer. There is no second
preview to keep in sync, which is the part that usually goes wrong in editors
with a live preview pane.

ctrl+s saves. Quitting with unsaved work asks first. enter continues the list
you are in, so the same bullet, the next number, or an unchecked box for a task,
and pressing it on an empty item ends the list. There is no selection and no cut
and paste. This is for fixing a typo and adding a paragraph. Your editor is still
your editor.

Two dependencies, not forty

The old parser was a few hundred lines of hand-rolled regex, and it got reference
links, nested lists and bare URLs wrong. Every fix was another regex.

Parsing moved to marked. The reason it won was not features, it was weight:
marked is CommonMark plus GFM with zero dependencies of its own. readm3 went
from one dependency to two. markdown-it would have been seven. A remark and
micromark pipeline is somewhere between twenty and forty packages, for a program
whose whole point is that it starts instantly in a terminal.

Only the parsing moved. The layout code that wraps text, draws code gutters and
sizes tables is untouched, so readm3.com still renders through the exact same
functions the terminal does. There is still no second renderer.

The swap fixed reference links, nested and loose lists, bare URL autolinks and
hard line breaks for free.

The dialects actually disagree

marked does not ship GitHub alerts, footnotes, :emoji:, or anything Reddit
added. Those are tokenizer extensions in readm3 now, still with no new
dependency.

They are behind a --flavor switch rather than all on at once, because the
dialects contradict each other in ways that matter:

2^32 is a number in a README. On Reddit it is 2 to the 32nd, rendered as a
superscript. Turn Reddit superscript on globally and every exponent in every
technical document silently changes meaning.

>!spoiler!< is worse. In CommonMark, and GitHub, and everywhere else, a line
starting with > is a blockquote, so that text parses as a quote containing
!spoiler!<. Reddit reads it as a spoiler. Getting that right needed a
block-level extension that claims the line before marked's blockquote tokenizer
ever sees it.

So: commonmark, github (the default), reddit, or all.

Small things that came out of building it. Superscript uses real Unicode glyphs
when every character has one, so mc^2 becomes mc², and keeps its caret when
they do not, because Unicode has no superscript q. Spoilers are blocked out with
solid blocks instead of being colored to match the background, so they stay
hidden when you pipe the output somewhere or run with --color never.

The bug a unit test would never have found

I drove the finished UI in a real pty and pressed ? for help while in edit
mode. It typed a question mark into the file.

Obvious in hindsight. ? is a character when there is a caret in the document.
The status bar was still advertising it as the help key, inherited from the
reader. Help moved to ctrl+g. No unit test was ever going to catch that,
because the buffer behaved perfectly: it inserted the character it was given.

144 tests, green on Node 22, Node 24 and Bun, across Linux, macOS and Windows.

bun add -g @profullstack/readm3
Enter fullscreen mode Exit fullscreen mode

https://readm3.com

Top comments (0)