Write upside down using Unicode IPA characters
Submitted by Christoph on 20 October, 2008 - 16:34
¡ǝpoɔıun oʇ sʞuɐɥʇ uʍop ǝpısdn ǝʇıɹʍ uɐɔ noʎ 'ʇou ɹo ʇı ǝʌǝılǝq.
This is nothing new (see [1] or [2]), but I wrote a small Python program for this to pipe my instant messaging through it. Needless to say that with KDE's Kopete I found yet another application that seems not to work with non-ASCII characters.
Anyway, here's the code:
#!/usr/bin/python # -*- coding: utf8 -*- """ Simple program that flips the input on stdin for latin characters. Support for diacritics through combining diacritical marks. Depends on proper rendering though. 2008 Christoph Burgmer (uyhc@stud.uni-karlsruhe.de) ˙ǝɹɐʍʇɟos ǝɥʇ uı sƃuılɐǝp ɹǝɥʇo ɹo ǝsn ǝɥʇ ɹo ǝɹɐʍʇɟos ǝɥʇ ɥʇıʍ uoıʇɔǝuuoɔ uı ɹo ɟo ʇno 'ɯoɹɟ ƃuısıɹɐ 'ǝsıʍɹǝɥʇo ɹo ʇɹoʇ 'ʇɔɐɹʇuoɔ ɟo uoıʇɔɐ uɐ uı ɹǝɥʇǝɥʍ 'ʎʇılıqɐıl ɹǝɥʇo ɹo sǝƃɐɯɐp 'ɯıɐlɔ ʎuɐ ɹoɟ ǝlqɐıl ǝq sɹǝploɥ ʇɥƃıɹʎdoɔ ɹo sɹoɥʇnɐ ǝɥʇ llɐɥs ʇuǝʌǝ ou uı ˙ʇuǝɯǝƃuıɹɟuıuou puɐ ǝsodɹnd ɹɐlnɔıʇɹɐd ɐ ɹoɟ ssǝuʇıɟ 'ʎʇılıqɐʇuɐɥɔɹǝɯ ɟo sǝıʇuɐɹɹɐʍ ǝɥʇ oʇ pǝʇıɯıl ʇou ʇnq ƃuıpnlɔuı 'pǝıldɯı ɹo ssǝɹdxǝ 'puıʞ ʎuɐ ɟo ʎʇuɐɹɹɐʍ ʇnoɥʇıʍ '"sı sɐ" pǝpıʌoɹd sı ǝɹɐʍʇɟos ǝɥʇ ˙ǝɹɐʍʇɟos ǝɥʇ ɟo suoıʇɹod lɐıʇuɐʇsqns ɹo sǝıdoɔ llɐ uı pǝpnlɔuı ǝq llɐɥs ǝɔıʇou uoıssıɯɹǝd sıɥʇ puɐ ǝɔıʇou ʇɥƃıɹʎdoɔ ǝʌoqɐ ǝɥʇ :suoıʇıpuoɔ ƃuıʍolloɟ ǝɥʇ oʇ ʇɔǝɾqns 'os op oʇ pǝɥsıuɹnɟ sı ǝɹɐʍʇɟos ǝɥʇ ɯoɥʍ oʇ suosɹǝd ʇıɯɹǝd oʇ puɐ 'ǝɹɐʍʇɟos ǝɥʇ ɟo sǝıdoɔ llǝs ɹo/puɐ 'ǝsuǝɔılqns 'ǝʇnqıɹʇsıp 'ɥsılqnd 'ǝƃɹǝɯ 'ʎɟıpoɯ 'ʎdoɔ 'ǝsn oʇ sʇɥƃıɹ ǝɥʇ uoıʇɐʇıɯıl ʇnoɥʇıʍ ƃuıpnlɔuı 'uoıʇɔıɹʇsǝɹ ʇnoɥʇıʍ ǝɹɐʍʇɟos ǝɥʇ uı lɐǝp oʇ '("ǝɹɐʍʇɟos" ǝɥʇ) sǝlıɟ uoıʇɐʇuǝɯnɔop pǝʇɐıɔossɐ puɐ ǝɹɐʍʇɟos sıɥʇ ɟo ʎdoɔ ɐ ƃuıuıɐʇqo uosɹǝd ʎuɐ oʇ 'ǝƃɹɐɥɔ ɟo ǝǝɹɟ 'pǝʇuɐɹƃ ʎqǝɹǝɥ sı uoıssıɯɹǝd ǝsuǝɔıl ʇıɯ :ǝsuǝɔıl """ import sys import locale import unicodedata BASE_LATIN_FLIP = u"ɐqɔpǝɟƃɥıɾʞlɯuodbɹsʇnʌʍxʎz" OTHERS_FLIP = {'!': u'¡', '?': u'¿', '(': ')', '{': '}', ';': u'؛', '>': '<', '\'': ',','.': u'˙'} # See: # http://de.wikipedia.org/wiki/Unicode-Block_Kombinierende_diakritische_Zeichen UNICODE_COMBINING_DIACRITICS = {u'̈': u'̤', u'̊': u'̥', u'́': u'̗', u'̀': u'̖', u'̇': u'̣', u'̃': u'̰', u'̄': u'̱', u'̂': u'̬', u'̆': u'̯', u'̌': u'̭', u'̑': u'̮', u'̍': u'̩'} TRANSLITERATIONS = {u'ß': 'ss'} # character lookup charLookup = dict([(unichr(charOrd), BASE_LATIN_FLIP[i]) for i, charOrd \ in enumerate(range(ord('a'), ord('z') + 1))]) charLookup.update(OTHERS_FLIP) for char in charLookup.copy(): charLookup[charLookup[char]] = char # lookup for diacritical marks diacriticsLookup = dict([(UNICODE_COMBINING_DIACRITICS[char], char) \ for char in UNICODE_COMBINING_DIACRITICS]) diacriticsLookup.update(UNICODE_COMBINING_DIACRITICS) _, default_encoding = locale.getdefaultlocale() line = sys.stdin.readline().decode(default_encoding) while line: line = line.strip("\n").lower() for char in TRANSLITERATIONS: line = line.replace(char, TRANSLITERATIONS[char]) input = list(line) input.reverse() output = [] for char in input: if char in charLookup: output.append(charLookup[char]) else: charNormalised = unicodedata.normalize("NFD", char) for c in charNormalised: if c in charLookup: charNormalised = charNormalised.replace(c, charLookup[c]) elif c in diacriticsLookup: charNormalised = charNormalised.replace(c, diacriticsLookup[c]) output.append(unicodedata.normalize("NFC", charNormalised)) print "".join(output).encode(default_encoding) line = sys.stdin.readline().decode(default_encoding)
Update: It seem that Fonts currently only support a fixed set of common character-diacritics combinations. There is a discussion currently on the Unicode mailing list about a more general algorithm that could place diacritical marks, then allowing for a wider range of support.