Generating Shorthand SVG in JavaScript
Long-time readers will know that I’m a fan of shorthand, even though I don’t get many opportunities to practice it these days. One of the reasons it’s difficult to practice it is that most of your practice should be reading well-written shorthand, and that’s hard to come by these days.
I have long entertained the idea of teaching a computer to write shorthand, because then it would be possible to take a web page and translate it into shorthand to force reading practice.
I thought generating the actual character shapes and connecting them would be difficult, but it turns out at least for the Melin system it is not so difficult. I tried doing it for a few letters early in the alphabet, and generally it takes just one or two cubic Bezier segments to encode the shape of the entire character.
This example is generated from the following JavaScript
render(document.getElementById('surface'), compose([
F, A, G, H, I
]));
where the compose
function currently does nothing, the render
function is
defined as
const render = (svg, chs) => { // Starting point and scale. let [ox, oy, sc] = [100, 200, 50]; for (const c of chs) { // Get definition of character. const d = c(ox, oy, sc); // Output all path segments for character. for (const p of d.path) { svg.appendChild(p); } // Update starting point for next character. [ox, oy] = [d.ex, d.ey]; } };
and a character is defined as e.g.
const G = (ox, oy, sc) => { const [ex, ey] = [ ox+0.5*sc, oy+0.33*sc ]; const swirl = svg_path(` M${ox},${oy} C${ox+1.0*sc},${oy-0.5*sc} ${ox+0.25*sc},${oy-1.0*sc} ${ox},${oy} C${ox-0.15*sc},${oy+0.5*sc} ${ex-0.5*sc},${ey+0.25*sc} ${ex},${ey} `); return { name: 'G', path: swirl, ex, ey }; };
The things that would need to be done to make this work for real are:
- Define Bezier curves for all characters (annoying to do by hand, but could be
made more efficiently with some cleverness. Reusability opportunity is large
due to the systematic nature of Melin. Might require a different interface for
characters, to be able to modify them more easily, like
extend_backstroke(K)
to create the character forSk
for example.) - Implement the
compose
function properly to modify characters as needed (some characters are rotated a bit when occurring in sequence in order not to run into each other, for example.) - Create a dictionary that allows the computer to use characters corresponding to common letter sequences.
- Find a way to lay out the shorthand words in such a way that they don’t run into each other on consecutive lines, for example.
I don’t expect these things to be very difficult to do, only time-consuming. But also time-consuming in a way which an llm might not help much with. Unfortunate! It would be so neat to have the finished software.