At work I work with Terraform, so need to edit quite a lot of tf files
in GNU Emacs. There's no built-in terraform-ts-mode Emacs package and
I don't want to install regexp-based terraform-mode package
Existing terraform-ts-mode is this: kgrotel/terraform-ts-mode, which
claims being experimental. So it's a good opportunity to learn how to
create major modes using Tree Sitter and on <2026-05-05 Tue> I built
my own with Claude Code.
Let's see if I'm going to use it, if yes – will think about publishing
a release. If you want to build it – clone the repo and ask Claude
Code to build it.
Trying org-tufte for public notes
On <2026-04-28 Tue> I tried to add footnotes to notes in Textpod. It
works, {C-c C-x f} adds a footnote link. Then publishing works
normally, just make sure footnotes heading is level down of the
published note (usually h2).
But, footnotes looks ugly, and rendered at the bottom. I want
sidenotes, as in Tufte CSS. I remember org-tufte exporter, so decided
to try. Apparently, there's newer version exists -
Zilong-Li/org-tufte. Let's try it.
(use-package org-tufte :ensure nil)
Export to plain HTML looks fine, side-notes as footnotes work
fine
this is side note, but in Org file it's actually a footnote!
. But when exporting into Textpod – body only, + custom
HTML and JS injected – it breaks.
On <2026-04-27 Mon> I'm once again fascinated how bad Markdown is
and how broken the export is. So for Textpod I decided to skip Markdown,
and export notes directly from Org to HTML.
Problem
Markdown can't handle lists properly.
This Org Mode block:
- github :: [[https://github.com/inanimate-tech/mist][inanimate-tech/mist]]
- posts ::
- [[https://interconnected.org/home/2026/02/12/mist][mist: Share and edit Markdown together, quickly (Interconnected)]]
- [[https://interconnected.org/home/2026/04/10/open-mist][mist is now open source and looking for interop (Interconnected)]]
: curl https://mist.inanimate.tech/new -T file.md
is exported as this Markdown block:
- **github:** [inanimate-tech/mist](https://github.com/inanimate-tech/mist)
- **posts:** - [mist: Share and edit Markdown together, quickly (Interconnected)](https://interconnected.org/home/2026/02/12/mist)
- [mist is now open source and looking for interop (Interconnected)](https://interconnected.org/home/2026/04/10/open-mist)
curl https://mist.inanimate.tech/new -T file.md
(remoto-browse "torvalds/linux") ;; hangs for a minute on a slow connection
(remoto-browse "https://github.com/agzam/remoto.el")
(find-file "/github:nex-crm/wuphf@main:/CHANGELOG.md")
Obvious choices like Cloudflare Workers, Github Pages and all their
variants were ruled out as they require accounts, backed by big corps
while I wanted something indy.
Another round of improvements of textpod.el, a companion Emacs
package to Textpod.
Custom ID format - attribute name and prefix
Added two defcustom options in textpod.el:
textpod-id-property (default "TEXTPOD_ID") - name of the Org
property used to store the note id.
textpod-id-prefix (default "") - prefix prepended to ids when
stored, stripped before sending requests to the server.
Introduced textpod--strip-prefix helper and updated all id call
sites (textpod-open-current-note, textpod-org-heading-to-note,
textpod-org-region-to-note) to respect these configs.
textpod-set-id sets ID without creating a node
I need a function to create texpod id property without sending note to
the server. This is needed to submit old notes so they have proper
timestamp.
Added textpod-set-id: an interactive command that sets
textpod-id-property on the current heading (with textpod-id-prefix)
derived from a time as YYYYMMDDhhmmss, without making any HTTP
request.
No prefix arg → uses (current-time).
With prefix arg → prompts via org-read-date, so the note can be
back-dated before later uploading with textpod-org-heading-to-note.
Quickly getting to Textpod notes
Using Ack is possible, placing point on a file-name and pressing {H-RET} will
call visit-source and go directly to the line.
On <2026-04-21 Tue> I rewritten Textpod from Rust to Go.
While I'm on vacation with the new MacBook Pro M4 Pro and I have
installed only bare minimum on it, I don't have Rust toolchain but do
have Go. So, asked Claude to do rewrite. The only external
dependency is goldmark package to render Markdown as HTMLs.
JuliusBrussee/cavekit: A Claude Code plugin that turns natural
language into blueprints, blueprints into parallel build plans, and
build plans into working software with automated iteration,
validation, and cross-model peer review.
forrestchang/andrej-karpathy-skills: A single CLAUDE.md file to
improve Claude Code behavior, derived from Andrej Karpathy's
observations on LLM coding pitfalls.
textpod-org-region-to-note: Convert the Org region between BEG and END to Markdown and send to Textpod.
textpod-org-heading-to-note: Send the current heading’s subtree to Textpod.
textpod-open-current-note: Open the current heading’s Textpod note in a browser.
When creating a note, textpod.el sets TEXTPOD_ID property that's equal
to node'id.
Change separator in notes.md to ^L
Default separator \n\n---\n\n is fragile as it requires exactly two
newlines before / after the note. I often messed up notes when
editing notes.md file manually. To fix that, I replaced it with ^L
character (insert in Emacs via C-q C-l) which usually represents new
pages.
Fix attachments links
Attachement links need to respect --base-path flag.
Handling attachments
My current workflow:
Assets are stored next to Notes under assets/ directory
I can quickly search for them, then open in Emacs/qView:
An image is a link to an image file that does not have a description part (Images (The Org Manual)).
Textpod already support images. What happens when I drag-n-drop an
image file to the textarea? Textpod copies them under attachments
directory.
What I want:
When creating a public note containing an image via API (using
textpod.el), copy the asset to assets/ directory, mimicing the directory
structure in the notes.
I need another API endpoint - POST /notes/assets/<name>, accepting
binary as payload.
Okay, I implemented it, let's test.
textpod-org-heading-to-note
Prompt: Implement textpod-org-heading-to-note function, it should select
current (top) heading - the one that has TEXTPOD_ID parameter, and
call textpod-org-region-to-note on it.
The command {M-x textpod-org-heading-to-note} works!
Should the textpod id be just id?
Currently I use TEXTPOD_ID property. If using ID property, notes will
automatically become Org-roam nodes. Currently IDs are generated as
timestamps via (setq org-id-method 'ts) with nanoseconds precision.
Then it will come with seconds precision. I will need to a prefix, to
be able to quickly find them (e.g. with {M-x deadgrep}).
Wrap h3 into details on index page
To declutter the index page, h3 markdown headings (h2 Org headings)
are wrapped into <details> tag. The note page renders normally,
showing table of contents on the left sidebar.