I Should Be a Yak Barber

I’ve spent four months on a series of side quests. I didn’t want to. It was more like I had to.

In March, I mentioned that the current roadmap for Mensago Connect are the following:

  • Rich text editing, a.k.a. text styling
  • Note import and export
  • Cloud sync

I was aware that the first of those three features would probably not be easy. I had no idea how right I was: four months shaving yaks. How so? Read on.

The Search for a Word Processor

My original vision was to find a good existing word processor component to drop into Connect, attach a carefully-crafted toolbar, and really start integrating it in with the rest of the app. Looking back, I have to laugh, because the landscape of options is… less than ideal.

After doing some initial research, I first looked at RichTextFX and Gluon’s Rich-Text-Area and started looking at the latter more deeply. After digging a bit deeper, using it would have either cost me a pretty penny or would have forced me to change the source code license, which I really didn’t want to if I didn’t have to. I tested it a bit and almost immediately found significant bugs, of which some were trivial to fix and, yet, remained unfixed. I just looked at the repository and, unless I missed something, there was no activity for just shy of a year. Couple that with a lack of support for inline images and other very helpful features, I just couldn’t do it.

With Rich-Text-Area not being very viable, I turned to RichTextFX. It felt like I didn’t have much choice, so despite the lack of generally-useful documentation, I pushed through. Unlike other solutions you typically see, it’s more of a toolkit that you can use to build a word processor. It really needs a Some Assembly Required warning on the label. All the projects that I saw using it were code editors and IDEs, so a buggy demo was my only real documentation or point of reference. I persisted and even managed to get to the point of having a kinda-sorta working demo, but I found a significant bug that so far has been ignored. The repository for RichTextFX also hasn’t seen any real activity in quite some time, as well. All my efforts were not in vain, though, and I have a much better understanding of how a word processor can work.

Writing a New Markup Language

While building my word processor demo, I realized that while I could edit and style text a bit, I didn’t have a way to load or save it in a format that would retain the styling. What did I do? Start working on a Kotlin implementation of a Safe Document Format (SDF) parser. The only problem was that I never really wrote a parser before.

Fortunately for me, I’d been dabbling in programming language design, so I knew a little bit about what was involved in writing one. Along the way I got the impression that for production you normally use a parser generator for the best speed and reliability instead of writing one by hand, so I spent two weeks learning about the ANTLR parser generator. I also spent those two weeks learning that writing a grammar that actually works is much harder than it looks. Or at least it was for me, anyway. I gave up and wrote one by hand, and it’s actually pretty good, I think, and I had the benefit of being able to handle errors exactly how I wanted to.

Once I had a working format parser, I could actually start building into the word processor demo. I did, and promptly found adjustments I needed to make to SDF. No specification survives its first implementation, apparently, but SDF is better for it.

Settling… For Now

With all of the frustrations and challenges I ran into with RichTextFX and the probability that I would have to fix its problems myself if I wanted something that actually worked as advertised. I was done, and began looking for alternatives, even going so far as to ask Reddit, the outcome of which is always uncertain. The responses? A commercial JavaScript rich text editor with a stripped-down open source version and a component from Java Swing. The Swing option required either changing toolsets or a kind of half-working square peg-round hole embedded situation. Nope. I ended up settling on an HTML editor component provided by the toolkit I was using.

I don’t like HTML. Because of its permissiveness, it’s hard to parse and errors are common. JavaScript is… not my favorite. CSS is complicated, but fine. The HTML editor control is not very configurable and has some problems, one of which I’ve already worked around. This is the result:

Next Steps

What now? Probably catch my breath for a moment, then finally make some forward significant progress again. I hope. Only one way to find out.