#! /usr/bin/env python
# -*- coding: utf-8 -*-

"""
Muthanna: Bidirectional and shaping filter, a BiDiv Replacement
 by Muayyad Alsadi
 Released under terms of GNU GPL v2
 right now BiDi is working through fribidi
 to display a UTF-8 file in a UNICODE enabled terminal (see unicode_start) type
    mu < FILE.txt | less

 mu /moo/
   The correct answer to the classic trick question
   "Have you stopped beating your wife yet?".
    
    a Japanese word alleged to mean
    "Your question cannot be answered because it depends on incorrect assumptions".
    The word `mu' is actually from Chinese, meaning `nothing'; it is used in
   mainstream Japanese in that sense.
   
   Jargon File
"""

from pyfribidi import *
import sys

# generated by ./joining.pl from ArabicShaping.txt then edited by hand
# char:TRL (4: trans, 2: joins with previous, 1: joins with next char)
joinings = {
  u"\u0622":2, u"\u0623":2,  u"\u0624":2,  u"\u0625":2,
  u"\u0626":3,
  u"\u0627":2,
  u"\u0628":3,
  u"\u0629":2,
  u"\u062A":3, u"\u062B":3, u"\u062C":3, u"\u062D":3, u"\u062E":3, 
  u"\u062F":2, u"\u0630":2, u"\u0631":2, u"\u0632":2,
  u"\u0633":3, u"\u0634":3, u"\u0635":3, u"\u0636":3, u"\u0637":3, u"\u0638":3, u"\u0639":3, u"\u063A":3, 
  u"\u0640":7, 
  u"\u0641":3, u"\u0642":3, u"\u0643":3, u"\u0644":3, u"\u0645":3, u"\u0646":3, u"\u0647":3,
  u"\u0648":2,
  u"\u0649":3, u"\u064A":3, u"\u064B":3, u"\u064C":3, u"\u064D":3, u"\u064E":3, u"\u064F":3, u"\u0650":3, u"\u0651":3, u"\u0652":3, u"\u0653":3, u"\u0654":3, u"\u0655":3, u"\u0656":3, u"\u0657":3, u"\u0658":3, u"\u0659":3, u"\u065A":3, u"\u065B":3, u"\u065C":3, u"\u065D":3, u"\u065E":3, u"\u065F":3, u"\u0660":3, u"\u0661":3, u"\u0662":3, u"\u0663":3, u"\u0664":3, u"\u0665":3, u"\u0666":3, u"\u0667":3, u"\u0668":3, u"\u0669":3, u"\u066A":3, u"\u066B":3, u"\u066C":3, u"\u066D":3, u"\u066E":3, u"\u066F":3, 
  u"\u0671":2, u"\u0672":2,  u"\u0673":2, u"\u0675":2, u"\u0676":2, u"\u0677":2,
  u"\u0678":3,
  u"\u0688":2, u"\u0689":2, u"\u068A":2, u"\u068B":2, u"\u068C":2, u"\u068D":2, u"\u068E":2, u"\u068F":2, u"\u0690":2, u"\u0691":2, u"\u0692":2, u"\u0693":2, u"\u0694":2, u"\u0695":2, u"\u0696":2, u"\u0697":2, u"\u0698":2, u"\u0699":2,
  u"\u069A":3, u"\u069B":3, u"\u069C":3, u"\u069D":3, u"\u069E":3, u"\u069F":3, u"\u06A0":3, u"\u06A1":3, u"\u06A2":3, u"\u06A3":3, u"\u06A4":3, u"\u06A5":3, u"\u06A6":3, u"\u06A7":3, u"\u06A8":3, u"\u06A9":3, u"\u06AA":3, u"\u06AB":3, u"\u06AC":3, u"\u06AD":3, u"\u06AE":3, u"\u06AF":3, u"\u06B0":3, u"\u06B1":3, u"\u06B2":3, u"\u06B3":3, u"\u06B4":3, u"\u06B5":3, u"\u06B6":3, u"\u06B7":3, u"\u06B8":3, u"\u06B9":3, u"\u06BA":3, u"\u06BB":3, u"\u06BC":3, u"\u06BD":3, u"\u06BE":3, u"\u06BF":3, 
  u"\u06C0":2,
  u"\u06C1":3,
  u"\u06C2":2, u"\u06C3":2, u"\u06C4":2, u"\u06C5":2, u"\u06C6":2, u"\u06C7":2, u"\u06C8":2, u"\u06C9":2, u"\u06CA":2, u"\u06CB":2,
  u"\u06CC":3,
  u"\u06CD":2,
  u"\u06CE":3,
  u"\u06CF":2,
  u"\u06D0":3, u"\u06D1":3 ,
  u"\u06D2":2, u"\u06D3":2, u"\u06D4":2, u"\u06D5":2,
  u"\u06EE":2, u"\u06EF":2,
  u"\u06FA":3, u"\u06FB":3, u"\u06FC":3,
  u"\u0710":2,
  u"\u0712":3, u"\u0713":3, u"\u0714":3, 
  u"\u0715":2, u"\u0716":2, u"\u0717":2, u"\u0718":2, u"\u0719":2,
  u"\u071A":3, u"\u071B":3, u"\u071C":3, u"\u071D":3, 
  u"\u071E":2,
  u"\u071F":3, u"\u0721":3,  u"\u0722":3,  u"\u0723":3,  u"\u0724":3,  u"\u0725":3,  u"\u0726":3, u"\u0727":3,
  u"\u0728":2,
  u"\u0729":3,
  u"\u072A":2,
  u"\u072B":3,
  u"\u072C":2,
  u"\u072D":3, u"\u072E":3,
  u"\u072F":2, u"\u0730":2, u"\u0731":2, u"\u0732":2, u"\u0733":2, u"\u0734":2, u"\u0735":2, u"\u0736":2, u"\u0737":2, u"\u0738":2, u"\u0739":2, u"\u073A":2, u"\u073B":2, u"\u073C":2, u"\u073D":2, u"\u073E":2, u"\u073F":2, u"\u0740":2, u"\u0741":2, u"\u0742":2, u"\u0743":2, u"\u0744":2, u"\u0745":2, u"\u0746":2, u"\u0747":2, u"\u0748":2, u"\u0749":2, u"\u074A":2, u"\u074B":2, u"\u074C":2, u"\u074D":2,
  u"\u074E":3, u"\u074F":3,
  u"\u200D":7
}

# generated by ./shapes.pl from UnicodeData.txt:
# converted from mu C header with perl -wpe 'y/[{}]/[\(\)]/;s/0x([0-9A-F]{4})/u"\\u$1"/gi; s/\s+\(/  /; s/,/:(/;' mu_shapes.h
# base: (iso, fin, ini, mid)
shapes = {
   u"\u0621":( u"\uFE80", u"\u0621", u"\u0621", u"\u0621" ),
   u"\u0622":( u"\uFE81", u"\uFE82", u"\uFE81", u"\uFE81" ), # fixed manually
   u"\u0623":( u"\uFE83", u"\uFE84", u"\uFE83", u"\uFE84" ), # fixed manually
   u"\u0624":( u"\uFE85", u"\uFE86", u"\u0624", u"\u0624" ),
   u"\u0625":( u"\uFE87", u"\uFE88", u"\uFE87", u"\uFE88" ), # fixed manually
   u"\u0626":( u"\uFE89", u"\uFE8A", u"\uFE8B", u"\uFE8C" ),
   u"\u0627":( u"\uFE8D", u"\uFE8E", u"\uFE8D", u"\uFE8E" ), # fixed manually
   u"\u0628":( u"\uFE8F", u"\uFE90", u"\uFE91", u"\uFE92" ),
   u"\u0629":( u"\uFE93", u"\uFE94", u"\u0629", u"\u0629" ),
   u"\u062A":( u"\uFE95", u"\uFE96", u"\uFE97", u"\uFE98" ),
   u"\u062B":( u"\uFE99", u"\uFE9A", u"\uFE9B", u"\uFE9C" ),
   u"\u062C":( u"\uFE9D", u"\uFE9E", u"\uFE9F", u"\uFEA0" ),
   u"\u062D":( u"\uFEA1", u"\uFEA2", u"\uFEA3", u"\uFEA4" ),
   u"\u062E":( u"\uFEA5", u"\uFEA6", u"\uFEA7", u"\uFEA8" ),
   u"\u062F":( u"\uFEA9", u"\uFEAA", u"\u062F", u"\u062F" ),
   u"\u0630":( u"\uFEAB", u"\uFEAC", u"\u0630", u"\u0630" ),
   u"\u0631":( u"\uFEAD", u"\uFEAE", u"\u0631", u"\u0631" ),
   u"\u0632":( u"\uFEAF", u"\uFEB0", u"\u0632", u"\u0632" ),
   u"\u0633":( u"\uFEB1", u"\uFEB2", u"\uFEB3", u"\uFEB4" ),
   u"\u0634":( u"\uFEB5", u"\uFEB6", u"\uFEB7", u"\uFEB8" ),
   u"\u0635":( u"\uFEB9", u"\uFEBA", u"\uFEBB", u"\uFEBC" ),
   u"\u0636":( u"\uFEBD", u"\uFEBE", u"\uFEBF", u"\uFEC0" ),
   u"\u0637":( u"\uFEC1", u"\uFEC2", u"\uFEC3", u"\uFEC4" ),
   u"\u0638":( u"\uFEC5", u"\uFEC6", u"\uFEC7", u"\uFEC8" ),
   u"\u0639":( u"\uFEC9", u"\uFECA", u"\uFECB", u"\uFECC" ),
   u"\u063A":( u"\uFECD", u"\uFECE", u"\uFECF", u"\uFED0" ),
   u"\u0641":( u"\uFED1", u"\uFED2", u"\uFED3", u"\uFED4" ),
   u"\u0642":( u"\uFED5", u"\uFED6", u"\uFED7", u"\uFED8" ),
   u"\u0643":( u"\uFED9", u"\uFEDA", u"\uFEDB", u"\uFEDC" ),
   u"\u0644":( u"\uFEDD", u"\uFEDE", u"\uFEDF", u"\uFEE0" ),
   u"\u0645":( u"\uFEE1", u"\uFEE2", u"\uFEE3", u"\uFEE4" ),
   u"\u0646":( u"\uFEE5", u"\uFEE6", u"\uFEE7", u"\uFEE8" ),
   u"\u0647":( u"\uFEE9", u"\uFEEA", u"\uFEEB", u"\uFEEC" ),
   u"\u0648":( u"\uFEED", u"\uFEEE", u"\u0648", u"\u0648" ),
   u"\u0649":( u"\uFEEF", u"\uFEF0", u"\uFBE8", u"\uFBE9" ),
   u"\u064A":( u"\uFEF1", u"\uFEF2", u"\uFEF3", u"\uFEF4" ),
   u"\u0671":( u"\uFB50", u"\uFB51", u"\u0671", u"\u0671" ),
   u"\u0677":( u"\uFBDD", u"\u0677", u"\u0677", u"\u0677" ),
   u"\u0679":( u"\uFB66", u"\uFB67", u"\uFB68", u"\uFB69" ),
   u"\u067A":( u"\uFB5E", u"\uFB5F", u"\uFB60", u"\uFB61" ),
   u"\u067B":( u"\uFB52", u"\uFB53", u"\uFB54", u"\uFB55" ),
   u"\u067E":( u"\uFB56", u"\uFB57", u"\uFB58", u"\uFB59" ),
   u"\u067F":( u"\uFB62", u"\uFB63", u"\uFB64", u"\uFB65" ),
   u"\u0680":( u"\uFB5A", u"\uFB5B", u"\uFB5C", u"\uFB5D" ),
   u"\u0683":( u"\uFB76", u"\uFB77", u"\uFB78", u"\uFB79" ),
   u"\u0684":( u"\uFB72", u"\uFB73", u"\uFB74", u"\uFB75" ),
   u"\u0686":( u"\uFB7A", u"\uFB7B", u"\uFB7C", u"\uFB7D" ),
   u"\u0687":( u"\uFB7E", u"\uFB7F", u"\uFB80", u"\uFB81" ),
   u"\u0688":( u"\uFB88", u"\uFB89", u"\u0688", u"\u0688" ),
   u"\u068C":( u"\uFB84", u"\uFB85", u"\u068C", u"\u068C" ),
   u"\u068D":( u"\uFB82", u"\uFB83", u"\u068D", u"\u068D" ),
   u"\u068E":( u"\uFB86", u"\uFB87", u"\u068E", u"\u068E" ),
   u"\u0691":( u"\uFB8C", u"\uFB8D", u"\u0691", u"\u0691" ),
   u"\u0698":( u"\uFB8A", u"\uFB8B", u"\u0698", u"\u0698" ),
   u"\u06A4":( u"\uFB6A", u"\uFB6B", u"\uFB6C", u"\uFB6D" ),
   u"\u06A6":( u"\uFB6E", u"\uFB6F", u"\uFB70", u"\uFB71" ),
   u"\u06A9":( u"\uFB8E", u"\uFB8F", u"\uFB90", u"\uFB91" ),
   u"\u06AD":( u"\uFBD3", u"\uFBD4", u"\uFBD5", u"\uFBD6" ),
   u"\u06AF":( u"\uFB92", u"\uFB93", u"\uFB94", u"\uFB95" ),
   u"\u06B1":( u"\uFB9A", u"\uFB9B", u"\uFB9C", u"\uFB9D" ),
   u"\u06B3":( u"\uFB96", u"\uFB97", u"\uFB98", u"\uFB99" ),
   u"\u06BA":( u"\uFB9E", u"\uFB9F", u"\u06BA", u"\u06BA" ),
   u"\u06BB":( u"\uFBA0", u"\uFBA1", u"\uFBA2", u"\uFBA3" ),
   u"\u06BE":( u"\uFBAA", u"\uFBAB", u"\uFBAC", u"\uFBAD" ),
   u"\u06C0":( u"\uFBA4", u"\uFBA5", u"\u06C0", u"\u06C0" ),
   u"\u06C1":( u"\uFBA6", u"\uFBA7", u"\uFBA8", u"\uFBA9" ),
   u"\u06C5":( u"\uFBE0", u"\uFBE1", u"\u06C5", u"\u06C5" ),
   u"\u06C6":( u"\uFBD9", u"\uFBDA", u"\u06C6", u"\u06C6" ),
   u"\u06C7":( u"\uFBD7", u"\uFBD8", u"\u06C7", u"\u06C7" ),
   u"\u06C8":( u"\uFBDB", u"\uFBDC", u"\u06C8", u"\u06C8" ),
   u"\u06C9":( u"\uFBE2", u"\uFBE3", u"\u06C9", u"\u06C9" ),
   u"\u06CB":( u"\uFBDE", u"\uFBDF", u"\u06CB", u"\u06CB" ),
   u"\u06CC":( u"\uFBFC", u"\uFBFD", u"\uFBFE", u"\uFBFF" ),
   u"\u06D0":( u"\uFBE4", u"\uFBE5", u"\uFBE6", u"\uFBE7" ),
   u"\u06D2":( u"\uFBAE", u"\uFBAF", u"\u06D2", u"\u06D2" ),
   u"\u06D3":( u"\uFBB0", u"\uFBB1", u"\u06D3", u"\u06D3" )
}

def do_a_shape(u,rl): return shapes.get(u,(u,u,u,u))[(rl&3)]
def shape(s):
  #tp,tn=0,0 # tp,tn type of previous, next
  jp,jc,jn=0,0,0 # jp,jn type of joining previous, current, next
  jpc,jcn=0,0 # jpc,jcn should previous-current, current-next be joind
  s=list(s)
  r=s;
  for i in xrange(len(s)-1):
    jn=joinings.get(s[i+1],0)
    jc=joinings.get(s[i],0)
    jpc=(jp & (jc>>1)) & 1
    jcn=(jc & (jn>>1)) & 1
    #if (jp & 1) and (jc & 2): jpc=1
    #else: jpc=0
    #if (jc & 1) and (jn & 2): jcn=1
    #else: jcn=0
    #if jn|4==4: continue # FIXME: transparent chars should be ignored in a smarter way
    #if debug: print jp,jc,jn,jpc,s[i],jcn, (jpc|(jcn<<1))
    r[i]=do_a_shape(s[i],(jpc|(jcn<<1)))
    jp=jc;
  i=len(s)-1
  jn=0;
  jc=joinings.get(s[i],0)
  if (jp & 1) and (jc & 2): jpc=1
  else: jpc=0
  if (jc & 1) and (jn & 2): jcn=1
  else: jcn=0
  #if debug: print jp,jc,jn,jpc,s[i],jcn, (jpc|(jcn<<1))
  r[i]= do_a_shape(s[i],(jpc|(jcn<<1)))
  #u'\uFEF5', u'\uFEF7', u'\uFEF9', u'\uFEFB' 
  #u'\uFEF6', u'\uFEF8', u'\uFEFA', u'\uFEFC'
  r=''.join(r)
  r=r.replace(u'\uFEE0\uFE8E',u'\uFEFC').replace(u'\uFEE0\uFE88',u'\uFEFA').replace(u'\uFEE0\uFE84',u'\uFEF8').replace(u'\uFEE0\uFE82',u'\uFEF6')
  r=r.replace(u'\uFEDF\uFE8E',u'\uFEFB').replace(u'\uFEDF\uFE88',u'\uFEF9').replace(u'\uFEDF\uFE84',u'\uFEF7').replace(u'\uFEDF\uFE82',u'\uFEF5')
  return r

def bidi(s): return log2vis(s,RTL)

if __name__=='__main__':
  #print bidi(shape(sys.stdin.read().decode('utf-8')))
  for F in sys.argv[1:]:
    f=file(F,'r') 
    for l in f.xreadlines():
      print bidi(shape(l.decode('utf-8'))).encode('utf-8'),

