Skip to content

Commit e27f14f

Browse files
authored
v2.1.0 (#44)
* initial work * fix CI * Work done * Fix README
1 parent c3c27eb commit e27f14f

11 files changed

+241
-102
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ wheels/
2424
*.egg-info/
2525
.installed.cfg
2626
*.egg
27+
.tox/
2728

2829
# Installer logs
2930
pip-log.txt

.travis.yml

+17-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
# https://travis-ci.org/mpcabd/python-arabic-reshaper
2-
dist: xenial
31
language: python
4-
python:
5-
- "2.7"
6-
- "3.5"
7-
- "3.6"
8-
- "3.7"
92
install:
10-
- "pip install -e ."
11-
script:
12-
- "python setup.py test"
3+
- pip install tox
4+
- pip install -e .
5+
matrix:
6+
include:
7+
- python: 2.7
8+
env:
9+
- TOX_ENV=py27
10+
- python: 3.6
11+
env:
12+
- TOX_ENV=py36
13+
- python: 3.7
14+
env:
15+
- TOX_ENV=py37
16+
- python: 3.8
17+
env:
18+
- TOX_ENV=py38
19+
script: tox -e $TOX_ENV

README.md

+45-2
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,45 @@ define an environment variable with the name
187187
to the configuration file. This way the reshape function will pick it
188188
automatically, and you won't have to change your old code.
189189

190+
## Settings based on a TrueType® font
191+
192+
If you intend to render the text in a TrueType® font, you can tell the library
193+
to generate its configuration by reading the font file to figure out what's
194+
supported in the font and what's not.
195+
196+
To use this feature you need to install the library with an extra option
197+
(not necessary when you install it with conda):
198+
199+
pip install --upgrade arabic-reshaper[with-fonttools]
200+
201+
Then you can use the reshaper like this:
202+
203+
```python
204+
import arabic_reshaper
205+
206+
reshaper = arabic_reshaper.ArabicReshaper(
207+
arabic_reshaper.config_for_true_type_font(
208+
'/path/to/true-type-font.ttf',
209+
arabic_reshaper.ENABLE_ALL_LIGATURES
210+
)
211+
)
212+
```
213+
214+
This will parse the font file, and figure out what ligatures it supports and enable them,
215+
as well as whether it has isolated forms or `use_unshaped_instead_of_isolated` should be
216+
enabled.
217+
218+
The second parameter to `config_for_true_type_font` can be one of
219+
220+
- `ENABLE_NO_LIGATURES`
221+
- `ENABLE_SENTENCES_LIGATURES`
222+
- `ENABLE_WORDS_LIGATURES`
223+
- `ENABLE_LETTERS_LIGATURES`
224+
- `ENABLE_ALL_LIGATURES` (default)
225+
226+
which controls what ligatures to look for, depending on your usage,
227+
see [default-config.ini](default-config.ini) to know what ligatures are there.
228+
190229
## Tashkeel/Harakat issue
191230

192231
[Harakat or Tashkeel](http://en.wikipedia.org/wiki/Arabic_diacritics#Tashkil_.28marks_used_as_phonetic_guides.29)
@@ -209,6 +248,10 @@ https://github.com/mpcabd/python-arabic-reshaper/tarball/master
209248

210249
## Version History
211250

251+
### 2.1.0
252+
253+
* Added support for settings based on a TrueType® font
254+
212255
### 2.0.14
213256

214257
* New option `use_unshaped_instead_of_isolated` to get around some fonts missing the isolated form for letters.
@@ -290,8 +333,8 @@ to Python.
290333
## Contact
291334

292335
Abdullah Diab (mpcabd)
293-
Email: mpcabd@gmail.com
294-
Blog: http://mpcabd.xyz
336+
Email: mpcabd@gmail.com
337+
Blog: http://mpcabd.xyz
295338

296339
For more info visit my blog
297340
[post here](http://mpcabd.xyz/python-arabic-text-reshaper/)

arabic_reshaper/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import os
22

33
from .arabic_reshaper import reshape, default_reshaper, ArabicReshaper
4+
from .reshaper_config import (config_for_true_type_font,
5+
ENABLE_NO_LIGATURES,
6+
ENABLE_SENTENCES_LIGATURES,
7+
ENABLE_WORDS_LIGATURES,
8+
ENABLE_LETTERS_LIGATURES,
9+
ENABLE_ALL_LIGATURES)
410

511

612
exec(open(os.path.join(os.path.dirname(__file__), '__version__.py')).read())

arabic_reshaper/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '2.0.15'
1+
__version__ = '2.1.0'

arabic_reshaper/arabic_reshaper.py

+7-76
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,14 @@
77
# Email: mpcabd@gmail.com
88
# Website: http://mpcabd.xyz
99

10-
# Ported and tweaked from Java to Python, from Better Arabic Reshaper
11-
# [https://github.com/agawish/Better-Arabic-Reshaper/]
12-
13-
# Usage:
14-
# Install python-bidi [https://github.com/MeirKriheli/python-bidi], can be
15-
# installed from pip `pip install python-bidi`.
16-
17-
# import arabic_reshaper
18-
# from bidi.algorithm import get_display
19-
# reshaped_text = arabic_reshaper.reshape('اللغة العربية رائعة')
20-
# bidi_text = get_display(reshaped_text)
21-
# Now you can pass `bidi_text` to any function that handles
22-
# displaying/printing of the text, like writing it to PIL Image or passing it
23-
# to a PDF generating method.
2410
from __future__ import unicode_literals
2511

2612
import re
27-
import os
2813

29-
from configparser import ConfigParser
3014
from itertools import repeat
31-
from pkg_resources import resource_filename
3215

3316
from .ligatures import LIGATURES
17+
from .reshaper_config import auto_config
3418
from .letters import (UNSHAPED, ISOLATED, TATWEEL, ZWJ, LETTERS_ARABIC,
3519
LETTERS_ARABIC_V2, LETTERS_KURDISH, FINAL,
3620
INITIAL, MEDIAL, connects_with_letters_before_and_after,
@@ -73,72 +57,19 @@ class ArabicReshaper(object):
7357
See the default configuration file :file:`default-config.ini` for details
7458
on how to configure your reshaper.
7559
"""
60+
7661
def __init__(self, configuration=None, configuration_file=None):
7762
super(ArabicReshaper, self).__init__()
7863

79-
configuration_files = [
80-
resource_filename(__name__, 'default-config.ini')
81-
]
82-
83-
if not os.path.exists(configuration_files[0]):
84-
raise Exception(
85-
('Default configuration file {} not found,' +
86-
' check the module installation.').format(
87-
configuration_files[0],
88-
)
89-
)
90-
91-
loaded_from_envvar = False
92-
93-
if not configuration_file:
94-
configuration_file = os.getenv(
95-
'PYTHON_ARABIC_RESHAPER_CONFIGURATION_FILE'
96-
)
97-
if configuration_file:
98-
loaded_from_envvar = True
99-
100-
if configuration_file:
101-
if not os.path.exists(configuration_file):
102-
raise Exception(
103-
'Configuration file {} not found{}.'.format(
104-
configuration_file,
105-
loaded_from_envvar and (
106-
' it is set in your environment variable ' +
107-
'PYTHON_ARABIC_RESHAPER_CONFIGURATION_FILE'
108-
) or ''
109-
)
110-
)
111-
configuration_files.append(configuration_file)
112-
113-
configuration_parser = ConfigParser()
114-
configuration_parser.read(
115-
configuration_files
116-
)
117-
118-
if configuration:
119-
configuration_parser.read_dict({
120-
'ArabicReshaper': configuration
121-
})
122-
123-
if 'ArabicReshaper' not in configuration_parser:
124-
raise ValueError(
125-
'Invalid configuration: '
126-
'A section with the name ArabicReshaper was not found'
127-
)
128-
129-
configuration = configuration_parser['ArabicReshaper']
130-
self.configuration = configuration
64+
self.configuration = auto_config(configuration, configuration_file)
13165
self.language = self.configuration.get('language')
13266

133-
13467
if self.language == 'ArabicV2':
13568
self.letters = LETTERS_ARABIC_V2
13669
elif self.language == 'Kurdish':
13770
self.letters = LETTERS_KURDISH
13871
else:
13972
self.letters = LETTERS_ARABIC
140-
141-
14273

14374
@property
14475
def _ligatures_re(self):
@@ -215,15 +146,15 @@ def reshape(self, text):
215146
previous_letter = output[-1]
216147
if previous_letter[FORM] == NOT_SUPPORTED:
217148
output.append((letter, isolated_form))
218-
elif not connects_with_letter_before(letter,self.letters):
149+
elif not connects_with_letter_before(letter, self.letters):
219150
output.append((letter, isolated_form))
220151
elif not connects_with_letter_after(
221-
previous_letter[LETTER],self.letters):
152+
previous_letter[LETTER], self.letters):
222153
output.append((letter, isolated_form))
223154
elif (previous_letter[FORM] == FINAL and not
224155
connects_with_letters_before_and_after(
225-
previous_letter[LETTER],self.letters
226-
)):
156+
previous_letter[LETTER], self.letters
157+
)):
227158
output.append((letter, isolated_form))
228159
elif previous_letter[FORM] == isolated_form:
229160
output[-1] = (

arabic_reshaper/ligatures.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
# This way we make sure we replace the longest ligatures first
2121

2222
from __future__ import unicode_literals
23+
from itertools import chain
2324

24-
LIGATURES = (
25-
# Sentences
25+
SENTENCES_LIGATURES = (
2626
('ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM', (
2727
'\u0628\u0633\u0645\u0020'
2828
'\u0627\u0644\u0644\u0647\u0020'
@@ -44,8 +44,9 @@
4444

4545
('\uFDFA', '', '', '')
4646
)),
47+
)
4748

48-
# Words
49+
WORDS_LIGATURES = (
4950
('ARABIC LIGATURE ALLAH', (
5051
'\u0627\u0644\u0644\u0647', ('\uFDF2', '', '', ''),
5152
)),
@@ -73,8 +74,9 @@
7374
('RIAL SIGN', (
7475
'\u0631[\u06CC\u064A]\u0627\u0644', ('\uFDFC', '', '', ''),
7576
)),
77+
)
7678

77-
# Letters
79+
LETTERS_LIGATURES = (
7880
('ARABIC LIGATURE AIN WITH ALEF MAKSURA', (
7981
'\u0639\u0649', ('\uFCF7', '', '', '\uFD13'),
8082
)),
@@ -927,3 +929,5 @@
927929
'\u0638\u0645', ('\uFC28', '\uFCB9', '\uFD3B', ''),
928930
)),
929931
)
932+
933+
LIGATURES = tuple(chain(SENTENCES_LIGATURES, WORDS_LIGATURES, LETTERS_LIGATURES))

0 commit comments

Comments
 (0)