2023-10-29

You. Have. Got. To. Be. F*<#!^&. Kidding. Me.

There must be things in the communication world that make me angrier that a computerized voice prompt system that makes "typing" noises at you while it works, but right now I can't think of one.

2023-10-16

Didn't expect it to be quite that hard

I'm getting my first non-trivial experience with JavaScript. It seemed like a good idea at the time.

Backing up to explain, I wanted to write a talk for my colleagues for some time. On C++ templates. Another thing that seemed like a good idea at the time.

Anyway, there is some interest around the office in a brown-bag lunch series, so I've actually gotten serious about writing it. And I want to own it, so I"m doing on my own time and resources, but that means I don't have a copy of PowerPoint. Not that I'd want to use PowerPoint, anyway, of course. Now in my academic days using $\LaTeX$1 would have been a no-brainer, but I've been watching conference talks given in various HTML/CSS/JavaScript engines recently and it seemed like an ideal time to try something like that out. Yep, seemed good idea again.

Enter reveal.js, but also a headache brought on by perfectionism.

You see, it's to be a talk about a feature of a programming language and that means code samples sprinkled throughout. No problem, reveal has support for that. Only it would be nice if the code samples were syntactically correct.2 So, I'd like to...

  1. include the text of external files in my presentation
  2. wrap that text in whatever html is needed to get reveal to mark it up as syntax highlighted code blocks
  3. be able to compile the code in a separate tool to check it's correctness

Well, number three is entirely on me and it's easy. But both of the other gave me some trouble though it turns out I didn't need to know how to do the second item at all.3

It was the inclusion problem (item 1) where I got the surprise. You see, html doesn't have an inclusion primitive. You have to use JavaScript if you want to do that on the client side.4 Fine. Apparently that was messy in the past, but modern JavaScript has fetch to get the contents of an external asset and lots of DOM nifftiness to stick it where you want it with various kinds of preprocessing (as html, as script, as text, and maybe some others).

So, in the first place I want a code sample I write a little script that runs code = fetch("myfile.h") and then inserts it in a useful place. Reload. Nothing appears. Force reload. Still nothing. Open the inspector and find the tag. The tag is empty. What? Check paths. Force reload. Still empty. Try with "./myfile.h". And with "/home/noswampcoolers/projects/template_thing/myfile.h".

At this point I took some time off to curse many things. Including my own ignorance, but mostly other people and tools. Debugging by rant. Or something.

Finally notice the tabs in the developer tools. Particularly the one named "Console" and the red decoration thingy. Oh, there's an error; something about a "same origin policy" not letting me do what I want. Even though the data file resides not only on the same filesystem but in the same directory.

More ranting, then hit the web for some education.

Turns out the same origin policy says what external data can be loaded without a security negotiation. But it's not terribly well named because while it does put limits on the origin it also imposes limits on the protocol.5 Short version: I'm going to need a web server running on my machine to fetch stuff from the local filesystem.

The first solution I found for just serving a named directory was python3 -m http.server --directory "$PWD" 8080 > server.log 2>&1 &, but I think I could probably do the same thing with some npm invocation which would be more elegant in the sense of using the same tool for both halves of the task. It's also not worth my time right now. Python it is.

So at this point I could load some external code into my presentation.6 But it wasn't getting highlighted the way it did if I wrote it right in the html file. Argh!

Maybe it has to do with the order various scripts run in. Check the web and try moving my bit around. Lots of places. No dice.

More reading suggested that I needed to integrate my code with the framework by writing plugin. And just for once in this saga I was smart enough to find at least three existing plugins before starting down that rabbit hole. No idea if the one I picked is the best, but it seems to work.

All-in-all a enlightening but rather disheartening epic to achieve what sounded like a little thing. I'm sure there is a deep story in how it got to be that way, starting with "first to market is more important that getting it right" and moving on through various pitfalls of the standards process. I'd love to read about it if someone else would research it.


1 For a long time I had a custom set of extensions to slides, but eventually I graduated to beamer.

2 Semantically as well, of course. For those fragments that have semantics. But that's a lot less amenable to automated validation.

3 The issue I had with the second item is that I wanted to show C++ template code, and that means things surrounded by angle brackets: < and > which is, of course, the tag syntax of html. Before I solved item one, I learned a trick for that. You can include the text as the contents of a script tag marked with attribute class="text/template".

4 Lots of choices on the server side, but lets not go there.

5 I was too focused on solving the problem in front of me to read into the details, but I suppose this has to do with preventing externally supplied code from reading your locally stored data and sending the it back to the mother-ship. Which would make sense but it still leads to a minor absurdity.

6 Somewhere along the way I'd also taken the time to run down a DRY solution to including many snippets and adapted it to produce the same "pre-code-script" nesting I had learned for including code directly in the file. Shout out to Mustafa even though I didn't end up using the code. Plus, I enjoyed recognizing the immediately-invoked lambda from it's use as an initializing idiom in C++.