Back to Index
This week, Professor Predrag Janičić and I released the web version of GCLC.
If you are not a mathematician, chances are that you never heard of GCLC. GCLC is a programming language/compiler for mathematical illustrations. The first version was created in 1995 by Professor Janičić, and since then the program has been constantly expanded with new features. Comparing it to some more popular tools, it sits somewhere between TikZ and Geogebra: users create illustrations by programming in custom Turing-complete language (just like in TikZ), but users also can move free points or play animations (just like in Geogebra). In its long tradition, GCLC has been used in countless mathematical publications.
GCLC comes as a console and a graphical program, with a graphical interface written in Qt. After GCLC was open-sourced in 2020, I worked with Professor Janičić on creating GitHub workflows for building executables for Windows and Linux. Even with great tools like aqtinstall and install-qt-action, writing such actions turned out to be nontrivial. Especially for Windows Qt build.
Last month, I was struggling again with GitHub workflows for the Qt6 build (until then we were on Qt5). While waiting for fresh builds from Github, I was poking around Qt6 docs looking at what the new version brings. The mention of WebAssembly caught my attention. I was thinking how inefficient such build would be, with a feeling that the current GCLC codebase is light years away from porting to WebAssembly. But then an idea struck my head: what if instead of compiling the Qt version of GCLC, I compiled the console version to WASM? Then I could make a simple upload button, write a few Javascript lines of glue code, and I would have an online console version….
As I had time to wait for a build, I dared to try. Not expecting success, but wanting to see where I will fail. After all, I have been planning for a long time to learn about WASM, and maybe this would be a good start. I installed Emscripten, changed Makefile
a little bit, and added emscripten.h
and EXTERN EMSCRIPTEN_KEEPALIVE
in the main C file.
To my great surprise first build was successful, and to my even greater surprise, the first run was successful! Yes, I got an error, but it was an error from GCLC (Input file not specified.
) not some random error from runtime. So, just like that, I (a wasm noob) in half-hour ported GCLC to wasm.
The next step was creating a web UI. I started very modestly, adding basic HTML elements (like checkboxes for command line flags). But, one by one, I slowly recreated 90% of the Qt interface. As I didn’t expect complex UI at the start I refrained from modern UI frameworks, and afterwards it was too late for any change. This made UI code, let’s say, nonconventional for modern standards. However, I couldn’t say no to TypeScript, and awesome libraries like CodeMirror and Panzoom. All in all, I don’t regret my UI architecture, but I do regret not writing end-to-end tests.
I would like to mention here some cool parts of web code (other than this it is very basic):
:hover
selector will not work on mobile phones, :focus
selector is used to show a dropdown menu. So, when the “hamburger button” gets the focus, it opens the dropdown that is next to it in the node tree. This is probably done already somewhere else, but I couldn’t find a similar implementation.There is still room for improvement, both for C++ and TypeScript code, but the next priority is creating a static Qt6 build. Even with the Qt5 version, we had problems distributing: the code would compile nicely but users would encounter errors produced by incompatibilities between dynamic libraries. If anyone wants to help us with the problem, feel free to contact us. I feel that my ignorance of C++ tools prevents me from solving this.
All code is in the GCLC repo.