Hacker News new | past | comments | ask | show | jobs | submit login

About a decade ago now, I was writing a group chat system of the Slack/Discord variety, and I was pondering how I'd like to support markup. I wanted to do something more powerful than just the regular "bold/emphasis/strikeout/links/etc." set, as the users of this group-chat were the type who would enjoy adding animations and other "effects" to their text, especially on top of their custom emoticons/stickers. (Don't fret, this wasn't team-productivity software ;)

What I ended up doing was extending the backend with support for parsing messages using a "command language"—essentially Tcl. The "everything is a string" feature of Tcl-like languages was essential, because I wanted these "commands" to be arbitrarily composable, and both the input and output were required to be strings (i.e. HTML), so commands couldn't pass data-structures to one-another; they had to accept strings, and emit strings.

The user was not allowed to enter arbitrary HTML in their message (this was filtered out as a pre-filtering step), but any Tcl command was allowed to take HTML-strings as input and emit HTML-strings as output, and the string that was eventually generated, HTML and all, was treated as the user's actual message. Many of the implemented commands would parse the input HTML-string into an AST, tweak it somehow, and then re-emit it as a string.

An example of such a command would be something like:

    And then [spoiler the protagonist died [rotate 5 [big :ohno:]]]
...where 'rotate' and 'big' layer together CSS effects (combining CSS classes with a bit of custom element style to parameterize it, with each rewriting the HTML AST structure of the previous to ensure the CSS effects "stack" correctly); and 'spoiler' is just a CSS class with pseudo-selector behaviors.

Another example would be:

   [type oh nooo[sfx fall]oooooooo]
...which would use a CSS class+JS trigger to display the message one character at a time the first time it became viewport-visible... and embed a hidden <audio> element at the top of the message body, that would get triggered as the typing progressed to it. Sort of like the dialogue event-scripting in a video game.

And, of course, just like an IRC bot, you could rely on the backend being Turing complete, in ways like:

   # generate random numbers
   [roll 1d6]

   # set a countdown timer on a user,
   # resetting it whenever the user talks
   [deadmanswitch 5mins I'm slacking off again!]

   # get the backend to (use a job queue to)
   # fetch a resource, plop it into its own download folder,
   # and then post a link to the retrieved copy
   [dl http://example.com] 

   # same, but also create a BitTorrent torrent for
   # the file, register it with a BT tracker on
   # the backend, and then emit the URL of the torrent file
   [torrent [dl http://example.com]]
---

At this point, I don't really think there's much room for a new group chat system; but this one feature was really cool to me, and I always wish I had seen it implemented in some bigger product.




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: