2025-06-30 Dynamic Content Without The Scripting (Re Gemini Scripting)
There was a series of articles on the topic of embedding scripts into Gemtext, so I thought I would chime in with my own thoughts and ideas:
Does the Spec Actually Allow Scripting?
While it is true that clients could support anything they want inside of gemtext, I personally think the spec explicitly disallows this, so it would not be spec-compliant. I don't think changes are actually needed to the spec. The reason why stems from what the blocks are: they are not script blocks, but *preformatted* blocks. And preformatted necessarily implies something that is displayed visually in a raw, already-formatted, form.
The gemtext spec talks about preformatted blocks very explicitly. In preformatted mode, *all* lines are text lines:
Any line which does not begin with the three characters "```" is a text line. In pre-formatted mode, text lines should be presented to the user in a "neutral", monowidth font without any alteration to whitespace or stylistic enhancements.
In addition, all lines must be parsed and rendered in isolation from each other:
A gemtext document can be correctly parsed and rendered by handling each line in isolation as it is encountered in a single pass from the first to last line.
Not only does the spec never mention the idea of execution, it also *always mentions* the idea of "rendering" or "display":
"Gemtext is designed to support simple electronic documents which can link to other online resources and which can be displayed in a manner conducive to easy and pleasant reading on devices with diverse display shapes and sizes."
"The essential structure of a gemtext document is flat, not hierarchical, and a document can be parsed and rendered correctly in a single top-to-bottom pass."
"A line's type, in conjunction with the parser state (see below) determines the manner in which it should be presented to the user."
"In pre-formatted mode, text lines should be presented to the user in a "neutral", monowidth font without any alteration to whitespace or stylistic enhancements."
A line's type determines presentation, it determines how the line is rendered, it determines how the text should be displayed. Not only does a line type not determine execution state (with one exception being preformatted toggles, which could be considered a change in execution state), the display of a line conflicts with execution.
Furthermore, in normal mode, text lines are exclusively presented for "general reading" and have "no special semantics":
Text lines have no special semantics and should be presented to the user in a visually pleasing manner for general reading, the precise meaning of which is at the client's discretion.
A script has semantics, so a script cannot be contained within normal mode text lines that explicitly have no special semantics.
Thus, while the spec could be even more specific, I do not think it needs to be at all. If people are going to implement scripting in gemtext, then they would already have to not care about the spec, in which case they would not care if the spec more explicitly disallowed this either.
Now, onto something more interesting...
A Working Idea
The ability to do very limited script-like things is what led me to think up some ideas for the Scroll Protocol. I've been keeping these in my head and notes for about a year now, but this topic had led me to typing out this idea.
The idea is for a streamable textual format for long-lived connections to servers where an additional linetype is added to a gemtext-like format that gives that line a variable name and some initial text. Then, the server can send another new linetype that sets that "variable" to a different text, and it would change the initial text inside the document to this new text.
Now don't get it confused. The use of "variable" here just means you are giving a particular text line a name. That's it, that's all. They don't store semantics or values. They only store text. They are simply text lines that you can update with yet more text later in the stream. Thus, this format would be streamed during a long-lived connection, waiting for any updates.
I came up with this idea primarily for chat systems where I wanted to update text of lines that were already sent to clients. I think it could also be used for live multiplayer or mmo games as well.
Another feature that I came up with is a new link linetype that *when clicked by the user* would send a request of a url with a query string to the server, but the server never responds back and the client stays connected to the page it was already on. These could be called something like *action links.* They perform an action, but have no response.
Then the server could send an update to this long-lived connection to change the text of a particular line within the document, by giving the line's name, and some text to update it to.
This format doesn't have proper scripting, it's just line text updates and links that request a "post" but don't respond. So it's completely "sandboxed", if you will, and the only tracking that could happen is from methods that already exist on gemini in the first place. It's also entirely possible to implement the text updates part of this idea within gemtext using VT100 ANSI escape sequences for terminal browsers, and that's because the idea is not particularly new, it's just in a new setting.
I am calling this new format scrollstream, because it's a format that utilizes text streaming, and it was originally designed for the scroll protocol. I think it could be great for chat and games over scroll (or gemini).