I was debugging a very strange case with one of my Node.js projects recently. It prints my output formatted (with the as-table module) into a nicely-looking ASCII table layout:
Clik here to view.

For the sake of even greater niceness, I tried replacing that “time” title with the 🕑 symbol from Unicode…
Clik here to view.

Whoa. Something wrong happened, obviously. Quite quickly I discovered that the computed length of symbol 🕑 turned out to be 2!
Initially, I suspected a bug in the module that incorrectly determined the true optical length of a string (it’s the printable-characters that does the job, BTW). WTF? Looks like you can’t rely on str.length to get its rendered length: you have to strip zero-width characters and ANSI escape sequences first, otherwise your string might end up being wider than it actually is!
So, I thought that 🕑.length could be erroneously computed as 2, and that miscalculation lead to an observed disruption of the table’s layout. That happens because the “clock”-symbol occupies multiple Unicode code points or something, and the built-in .length just isn’t smart enough to manage it. Here’s a thorough explanation of the issue and I highly recommend reading it:
Jonathan New | "💩".length === 2
…but then, suddenly, I realized one more thing. The actual visible width of 🕑 might be “2” indeed, from VSCode:
Clik here to view.

But not quite… As you can see, it is not exactly 2 nor 1(and that puts things out of alignment). But how do various console terminals render it? Check it out in VSCode’s Integrated Terminal:
Clik here to view.

…and the built-in terminal app from MacOS:
Clik here to view.

It seems that popular terminals render everything strictly monospaced, and it’s up to the user himself to put an empty space after each of those new fancy Unicode glyphs, to make room for them in a monospaced grid, manually:
Clik here to view.

Thus, our initial suggestion must have been true, and we should’ve patched printable-characters, enabling it to comprehend those symbols. The article referenced above helped me a lot with that task. So all essential bits required for a proper ASCII layout now work like a charm without breaking on zero-width characters, Emojis and ANSI escape codes:
// determining the real length of a string
strlen ('💩') === 1
// getting first N visible symbols
first ('💩23456789', 3) === '💩23'
// filling with whitespace
blank ('\t💩foo') === '\t '
Yay! Now the as-table is capable of rendering those fancy characters nicely:
Clik here to view.

About the Author
I’m a member of the developer team behind the open-source cross-language CCXT Library (available for JavaScript, Python or PHP). The library is used to connect and trade with more than 85 cryptocurrency exchanges worldwide.
Image may be NSFW.Clik here to view.
