python-negar 1.4.3__tar.gz → 1.4.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,8 @@
1
+ 1.4.4 - 2026-10-31
2
+ -- Fixed handling of Arabic words with diacritics (ایّام, بیمِ, بُستان, ناوِلْها): no wrong ZWNJ/separation
3
+ -- Immutable words are now matched ignoring diacritics
4
+ -- Added several additional immutable words.
5
+
1
6
  1.4.3 - 2025-01-28
2
7
  -- Save user defined immutable words under .config/python-negar
3
8
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: python-negar
3
- Version: 1.4.3
3
+ Version: 1.4.4
4
4
  Summary: Negar is a spell corrector and Persian text editor
5
5
  Home-page: http://github.com/shahinism/python-negar
6
6
  Author: Shahin Azad
@@ -18,6 +18,20 @@ Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  License-File: AUTHORS
20
20
  Requires-Dist: regex
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: keywords
28
+ Dynamic: license
29
+ Dynamic: license-file
30
+ Dynamic: maintainer
31
+ Dynamic: maintainer-email
32
+ Dynamic: requires-dist
33
+ Dynamic: requires-python
34
+ Dynamic: summary
21
35
 
22
36
  Negar
23
37
  ==========
@@ -31,6 +45,8 @@ Requires-Dist: regex
31
45
 
32
46
  Negar is an editor(=virastar in Persian) for Persian text. The project is initially inspired by [virastar](https://github.com/aziz/virastar/blob/master/lib/virastar.rb). Thank you [Aziz](https://github.com/aziz) for your great job.
33
47
 
48
+ ## [Demo View ![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://negar-web.streamlit.app/)
49
+
34
50
  Installation
35
51
  ==============
36
52
 
@@ -10,6 +10,8 @@
10
10
 
11
11
  Negar is an editor(=virastar in Persian) for Persian text. The project is initially inspired by [virastar](https://github.com/aziz/virastar/blob/master/lib/virastar.rb). Thank you [Aziz](https://github.com/aziz) for your great job.
12
12
 
13
+ ## [Demo View ![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://negar-web.streamlit.app/)
14
+
13
15
  Installation
14
16
  ==============
15
17
 
@@ -1,7 +1,7 @@
1
1
  import platform
2
2
  from pathlib import Path
3
3
 
4
- __version__ = "1.4.3"
4
+ __version__ = "1.4.4"
5
5
 
6
6
  DATAFILE = Path(__file__).parent.absolute() / "data/immutable.words"
7
7
  APPDATA = "AppData/Roaming/" if platform.system() == "Windows" else ".config/"
@@ -1915,4 +1915,10 @@
1915
1915
  یادداشتتان
1916
1916
  یاریتان
1917
1917
  یاقوت‌نشان
1918
- یاقوت‌نشان
1918
+ یاقوت‌نشان
1919
+ راستان
1920
+ بیارا
1921
+ بیائید
1922
+ بیایید
1923
+ عمان
1924
+ بیم
@@ -15,6 +15,9 @@ sys.path.append(
15
15
  from negar.constants import DATAFILE, INFO, URLREGX, USERFILE # noqa: E402
16
16
 
17
17
 
18
+ DIACRITICS = "\u064B-\u0652\u0670" # to be used inside a character class
19
+
20
+
18
21
  class State(enum.Enum):
19
22
  save = 1
20
23
  restore = 2
@@ -131,11 +134,18 @@ class PersianEditor:
131
134
  """Remove immutable words temporarily and reapply them at the end of the process."""
132
135
  if state == State.save:
133
136
  self.immutable_words = {}
134
- words = re.findall(r"\b[\w\u200c]+\b", self.text, re.UNICODE)
135
- for i, word in enumerate(words):
136
- if (word := word.strip()) in ImmutableWords.get():
137
- self.immutable_words[i] = word
138
- self.text = regex.sub(rf"\b{word}\b", rf"__IMM__#{i}__", self.text)
137
+
138
+ def protect(m):
139
+ # look up without diacritics (بُستان -> بستان) but keep them in the text
140
+ word = m.group()
141
+ if re.sub(f"[{DIACRITICS}]", "", word) not in ImmutableWords.get():
142
+ return word
143
+ i = len(self.immutable_words)
144
+ self.immutable_words[i] = word
145
+ return f"__IMM__#{i}__"
146
+
147
+ # diacritics are part of the word, otherwise `re` cuts it at them
148
+ self.text = re.sub(rf"\b[\w\u200c{DIACRITICS}]+", protect, self.text)
139
149
  if state == State.restore:
140
150
  for imm_key, imm_word in self.immutable_words.items():
141
151
  self.text = re.sub(f"__IMM__#{imm_key}__", imm_word, self.text)
@@ -228,7 +238,7 @@ class PersianEditor:
228
238
  def fix_suffix_spacing(self):
229
239
  """Put ZWNJ between a word and its suffix (*ha[ye] *tar[in])."""
230
240
  regx = re.compile(
231
- r"""\s+
241
+ r"""(?<![\u064B-\u0652\u0670])\s+ # a diacritic before the suffix means an Arabic word
232
242
  (تر(ی(ن)?)?
233
243
  |[تمش]ان
234
244
  |ا[متش]
@@ -237,7 +247,7 @@ class PersianEditor:
237
247
  |شناس(ی)?
238
248
  |گذار(ی)?|گزار(ی)?
239
249
  |مند|ور|پور
240
- )\b""",
250
+ )\b(?![\u064B-\u0652\u0670])""", # a trailing diacritic (e.g. ایّام) means the word goes on
241
251
  re.VERBOSE,
242
252
  )
243
253
  self.text = re.sub(regx, r"‌\1", self.text)
@@ -261,7 +271,7 @@ class PersianEditor:
261
271
  else ""
262
272
  )
263
273
  regx = regex.compile(
264
- rf"""\b(\S+?) # not-greedy fetch to handle some case like هایشان instead شان
274
+ rf"""\b(\S+?(?<![\u064B-\u0652\u0670])) # not-greedy fetch to handle some case like هایشان instead شان; no diacritic before the suffix
265
275
  ({exag}
266
276
  # تر(ی(ن)?)?
267
277
  # [تمش]ان|
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: python-negar
3
- Version: 1.4.3
3
+ Version: 1.4.4
4
4
  Summary: Negar is a spell corrector and Persian text editor
5
5
  Home-page: http://github.com/shahinism/python-negar
6
6
  Author: Shahin Azad
@@ -18,6 +18,20 @@ Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  License-File: AUTHORS
20
20
  Requires-Dist: regex
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: keywords
28
+ Dynamic: license
29
+ Dynamic: license-file
30
+ Dynamic: maintainer
31
+ Dynamic: maintainer-email
32
+ Dynamic: requires-dist
33
+ Dynamic: requires-python
34
+ Dynamic: summary
21
35
 
22
36
  Negar
23
37
  ==========
@@ -31,6 +45,8 @@ Requires-Dist: regex
31
45
 
32
46
  Negar is an editor(=virastar in Persian) for Persian text. The project is initially inspired by [virastar](https://github.com/aziz/virastar/blob/master/lib/virastar.rb). Thank you [Aziz](https://github.com/aziz) for your great job.
33
47
 
48
+ ## [Demo View ![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://negar-web.streamlit.app/)
49
+
34
50
  Installation
35
51
  ==============
36
52
 
@@ -134,6 +134,26 @@ class Test(unittest.TestCase):
134
134
  self.input_ = "تنها ترین خدمتگزار (تنها ترین خدمتگزار)"
135
135
  self.output_ = "تنهاترین خدمتگزار (تنهاترین خدمتگزار)"
136
136
 
137
+ @_assertEqual("Suffix With Diacritics")
138
+ def test_suffix_with_diacritics(self):
139
+ self.input_ = "غم ایّام"
140
+ self.output_ = "غم ایّام"
141
+
142
+ @_assertEqual("Suffix With Diacritics")
143
+ def test_suffix_with_diacritics_ii(self):
144
+ self.input_ = "غمِ ایّام"
145
+ self.output_ = "غمِ ایّام"
146
+
147
+ @_assertEqual("Immutable Word With Diacritics")
148
+ def test_immutable_word_with_diacritics(self):
149
+ self.input_ = "بیمِ جان بُستان"
150
+ self.output_ = "بیمِ جان بُستان"
151
+
152
+ @_assertEqual("Arabic Word Before Plural Suffix")
153
+ def test_arabic_word_before_plural_suffix(self):
154
+ self.input_ = "ناوِلْها اَهْمِلْها بُستان"
155
+ self.output_ = "ناوِلْها اَهْمِلْها بُستان"
156
+
137
157
  @_assertEqual("Fix Suffix ZWNJ II")
138
158
  def test_fix_suffix_ZWNJ_II(self):
139
159
  self.input_ = "بیستم ماه میلادی"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes