Flipping text upside-down
Wednesday, July 14, 2010
Over the last few years, there has been a recurring meme to flip text upside-down. You can find posts about it, online text-flipping services, and programming libraries (e.g., for Perl and Emacs).
All of these implementations seem to work the same way: find Unicode characters that resemble upside-down version of the latin alphabet and create a mapping that is used to turn text “upside-down”. Since Factor has strong support for Unicode, I thought it could use a library to flip strings.
What it should look like when we are done:
IN: scratchpad "abcdefghijklmnopqrstuvwxyz1234567890" flip-text .
"068Ɫ95ᔭƐᄅ⇂zʎxʍʌnʇsɹbdouɯʃʞɾᴉɥᵷɟǝpɔqɐ"
As is typical, we list our dependencies and create a namespace to hold the new functions:
USING: assocs kernel sequences ;
IN: flip-text
Next, we will create the character mapping (simply hard-coding the character lookups):
CONSTANT: CHARS H{
{ CHAR: a 0x0250 }
{ CHAR: b CHAR: q }
{ CHAR: c 0x0254 }
{ CHAR: d CHAR: p }
{ CHAR: e 0x01DD }
{ CHAR: f 0x025F }
...
And then, since it is useful to make the flip-text
word reversible
(e.g., return the original value if applied again), we will update the
mapping with the reverse entries:
CHARS [ CHARS set-at ] assoc-each
Mapping a single character is pretty straight-forward (making sure to pass the original character through if a mapping isn’t found):
: ch>flip ( ch -- ch' )
dup CHARS at [ nip ] when* ;
And then flipping a string of text is just a matter of flipping each character and reversing the string:
: flip-text ( str -- str' )
[ ch>flip ] map reverse ;
The complete implementation for this is on my GitHub account.