Skip to content
Tech News
← Back to articles

A font that reads what you wrote

read original more articles
Why This Matters

This story showcases a niche but clever font/library concept that automatically applies typographic emphasis based on the semantic and emotional content of text. While small in scope, it points to a broader trend of using lightweight NLP heuristics to enhance readability and expressiveness in everyday text rendering, which could influence UI design, accessibility tools, and content editors.

Key Takeaways

semfont is a small library that sets typography automatically. As you can see below it automatically highlights, colors, bolds, and italicizes text which aims to make it easier to read.

theme editorial loud monochrome technical

How it works

Every word gets four scores. Each one starts as a dictionary lookup and is then adjusted by a couple of rules over the words around it.

Valence is how good or bad the word is, from -1 to 1. A negator up to three words back flips the sign and damps it, because not great is a mild complaint rather than the mirror image of praise. An intensifier up to two words back scales it instead.

let v = VALENCE[word] ?? 0; // great -> 0.75 if (negatorWithin(3)) v = -v * 0.74; // not great -> -0.55 v *= gain; // really great -> 0.98

Salience is how much the word is worth looking at, 0 to 1. A frequency list gives each word a rarity, 0 for one of the hundred most common English words and 1 for one it has never seen. Rarity alone is not enough, so the score also rises with how often the word repeats in this particular text: an uncommon word you keep saying is what the text is about.

const seen = Math.min(1, (repeats - 1) / 2); const repetition = 0.45 + 0.55 * seen; let s = SALIENCE[word] ?? 0; s = Math.max(s, 0.55 * rarity * repetition); // rarity('the') 0.00, rarity('kubelet') 0.93 // kubelet said once -> 0.23 // kubelet said 3 times -> 0.51

Surprise is where the sentence turns, 0 to 1. Some words announce it on their own, like suddenly or ironically . Otherwise it comes from position: everything for six words after a contrast word gets it, decaying with distance, and so does any word much rarer than the rest of the passage.

let s = SURPRISE[word] ?? 0; // suddenly -> 0.85 if (afterContrast) { s = Math.max(s, 0.45 * 0.82 ** (distance - 1)); } s += 0.3 * Math.max(0, rarity - passageMeanRarity - 0.25); // 'The tests failed' -> failed 0.16 // 'It compiled, but the tests failed' -> failed 0.44

... continue reading