Package: arabic-reshaper
Python Arabic ReshaperReconstruct Arabic sentences to be used in applications that don't support
Arabic script.Works with Python 3.xDescriptionArabic script is very special with two essential features:It is written from right to left.The characters change shape according to their surrounding characters.So when you try to print text written in Arabic script in an application
– or a library – that doesn’t support Arabic you’re pretty likely to end up
with something that looks like this:We have two problems here, first, the characters are in the isolated form,
which means that every character is rendered regardless of its surroundings,
and second is that the text is written from left to right.To solve the latter issue all we have to do is to use theUnicode bidirectional algorithm, which is
implemented purely in Python inpython-bidi.
If you use it you’ll end up with something that looks like this:The only issue left to solve is to reshape those characters and replace them
with their correct shapes according to their surroundings. Using this library
helps with the reshaping so we can get the proper result like this:Installationpip install --upgrade arabic-reshaperIf you're using Anaconda you can useconda install -c mpcabd arabic-reshaperUsageimportarabic_reshapertext_to_be_reshaped='اللغة العربية رائعة'reshaped_text=arabic_reshaper.reshape(text_to_be_reshaped)Example using PIL ImagePIL Image does not support reshaping out of the box, so to draw Arabic text on anImageinstance you would need to reshape
the text for sure.For this example to work you need to runpip install --upgrade arabic-reshaper python-bidi pillowimportarabic_reshapertext_to_be_reshaped='اللغة العربية رائعة'reshaped_text=arabic_reshaper.reshape(text_to_be_reshaped)# At this stage the text is reshaped, all letters are in their correct form# based on their surroundings, but if you are going to print the text in a# left-to-right context, which usually happens in libraries/apps that do not# support Arabic and/or right-to-left text rendering, then you need to use# get_display from python-bidi.# Note that this is optional and depends on your usage of the reshaped text.frombidi.algorithmimportget_displaybidi_text=get_display(reshaped_text)# At this stage the text in bidi_text can be easily rendered in any library# that doesn't support Arabic and/or right-to-left, so use it as you'd use# any other string. For example if you're using PIL.ImageDraw.text to draw# text over an image you'd just use it like this...fromPILimportImage,ImageDraw,ImageFont# We load Arial since it's a well known font that supports Arabic Unicodefont=ImageFont.truetype('Arial',40)image=Image.new('RGBA',(800,600),(255,255,255,0))image_draw=ImageDraw.Draw(image)image_draw.text((10,10),bidi_text,fill=(255,255,255,128),font=font)# Now the text is rendered properly on the image, you can save it to a file or just call `show` to see it workingimage.show()# For more details on PIL.Image and PIL.ImageDraw check the documentation# See http://pillow.readthedocs.io/en/5.1.x/reference/ImageDraw.html?#PIL.ImageDraw.PIL.ImageDraw.Draw.textSettingsYou can configure the reshaper to your preferences, it has the following
settings defined:language(Default:'Arabic'): Ignored, the reshaper works with Arabic,
Farsi, and Urdu, and most probably all other languages that use Arabic script.support_ligatures(Default:True): When this is set toFalse, the
reshaper will not replace any ligatures, otherwise it will replace enabled
ligatures.delete_harakat(Default:True): When this is set toFalsethe reshaper
will not delete the harakat from the text, this will result in them showing up
in the reshaped text, you should enable this option if you are going to pass
the reshaped text tobidi.algorithm.get_displaybecause it will reverse the
text and you'd end up with harakat applied to the next letter instead of the
previous letter.delete_tatweel(DefaultFalse): When this is set toTruethe reshaper
will delete the Tatweel character (U+0640) from the text before reshaping, this
can be useful when you want to support ligatures and don't care about Tatweel
getting deleted.shift_harakat_position(DefaultFalse): Whether to shift the Harakat
(Tashkeel) one position so they appear correctly when string is reversed, this
might solve the problem of Tashkeel in some systems, although forPIL.Imagefor example, this is not needed.support_zwj(DefaultTrue): Whether to support ZWJ (U+200D) or not.use_unshaped_instead_of_isolated(DefaultFalse): Use unshaped form
instead of isolated form, useful in some fonts that are missing the isolated
form of letters.Besides the settings above, you can enable/disable supported ligatures. For a
full list of supported ligatures and their default status check the filedefault-config.ini.There are multiple ways that you can configure the reshaper in, choose the one
that suits your deployment:Via ArabicReshaper instanceconfigurationInstead of directly usingarabic_reshaper.reshapefunction, define an
instance ofarabic_reshaper.ArabicReshaper, and pass your config dictionary
to its constructor'sconfigurationparameter like this:fromarabic_reshaperimportArabicReshaperconfiguration={'delete_harakat':False,'support_ligatures':True,'RIAL SIGN':True,# Replace ر ي ا ل with ﷼}reshaper=ArabicReshaper(configuration=configuration)text_to_be_reshaped='سعر المنتج ١٥٠ ر'+'يال'# had to split the string for displayreshaped_text=reshaper.reshape(text_to_be_reshaped)Via ArabicReshaper instanceconfiguration_fileYou can separte the configuration from your code, by copying the filedefault-config.iniand change its settings,
then save it somewhere in your project, and then you can tell the reshaper
to use your new config file, just pass the path to your config file to its
constructor'sconfiguration_fileparameter like this:fromarabic_reshaperimportArabicReshaperreshaper=ArabicReshaper(configuration_file='/path/to/your/config.ini')text_to_be_reshaped='سعر المنتج ١٥٠ ر'+'يال'# had to split the string for displayreshaped_text=reshaper.reshape(text_to_be_reshaped)Where in youconfig.iniyou can have something like this:[ArabicReshaper]
delete_harakat = no
support_ligatures = yes
RIAL SIGN = yesViaPYTHON_ARABIC_RESHAPER_CONFIGURATION_FILEenvironment variableInstead of having to rewrite your old code to configure it like above, you can
define an environment variable with the namePYTHON_ARABIC_RESHAPER_CONFIGURATION_FILEand in its value put the full path
to the configuration file. This way the reshape function will pick it
automatically, and you won't have to change your old code.Settings based on a TrueType® fontIf you intend to render the text in a TrueType® font, you can tell the library
to generate its configuration by reading the font file to figure out what's
supported in the font and what's not.To use this feature you need to install the library with an extra option
(not necessary when you install it with conda):pip install --upgrade arabic-reshaper[with-fonttools]Then you can use the reshaper like this:importarabic_reshaperreshaper=arabic_reshaper.ArabicReshaper(arabic_reshaper.config_for_true_type_font('/path/to/true-type-font.ttf',arabic_reshaper.ENABLE_ALL_LIGATURES))This will parse the font file, and figure out what ligatures it supports and enable them,
as well as whether it has isolated forms oruse_unshaped_instead_of_isolatedshould be
enabled.The second parameter toconfig_for_true_type_fontcan be one ofENABLE_NO_LIGATURESENABLE_SENTENCES_LIGATURESENABLE_WORDS_LIGATURESENABLE_LETTERS_LIGATURESENABLE_ALL_LIGATURES(default)which controls what ligatures to look for, depending on your usage,
seedefault-config.inito know what ligatures are there.Tashkeel/Harakat issueHarakat or Tashkeelmight not show up properly in their correct place, depending on the application
or the library that is doing the rendering for you, so you might want to enable
theshift_harakat_positionoption if you face this problem.LicenseThis work is licensed underMIT License.DemoOnline Arabic Reshaper:http://pydj.mpcabd.xyz/arabic-reshaper/Downloadhttps://github.com/mpcabd/python-arabic-reshaper/tarball/masterVersion History3.0.0Stop supporting Python 2.7Remove dependency onfuture. See #88.2.1.4Fix unparseable version bound forfonttoolsunder Python 22.1.3Remove dependency on__version__.pyanddefault-config.inifiles, as they were causing problems for people who package their apps using pyinstaller or buildozer.2.1.1Fix a warning. See #57. Thanks @fbernhart2.1.0Added support for settings based on a TrueType® font2.0.14New optionuse_unshaped_instead_of_isolatedto get around some fonts missing the isolated form for letters.2.0.13BROKENplease make sure not to use this version.2.0.12Updated letters and ligaturesNew optionshift_harakat_positionto try to get around the Tashkeel problem2.0.11Proper support for ZWJ2.0.10Fix Shadda ligatures2.0.9Added support for ZWJ (Zero-width Joiner) (U+200D)2.0.8Addeddelete_tatweelAdded more test cases2.0.7Fix tests for Python 2.72.0.6Fixed a bug with Harakat breaking the reshapingWrote two small unit tests, more to comeMoved letters and ligatures to separate files for readability/maintainabilityMoved package to its own folder for readability/maintainability2.0.5Fix error message formatting2.0.4Fix error message formatting2.0.3UseExceptioninstead ofError.2.0.2Usepkg_resources.resource_filenameinstead of depending on__file__to accessdefault-config.ini.2.0.1Include default-config.ini in setup.py2.0.0Totally rewrote the code;Faster and better performance;Added the ability to configure and customise the reshaper.1.0.1New glyphs for Farsi;Added setup.py;Bugfixes.1.0PortedBetter Arabic Reshaperto Python.ContactAbdullah Diab (mpcabd)
Email:mpcabd@gmail.comBlog:http://mpcabd.xyzFor more info visit my blogpost here