Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion hazm/normalizer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""This module contains classes and functions for text normalization."""

import re
from typing import Final

from hazm.api import NormalizerProtocol
from hazm.constants import AFFIX_SPACING_PATTERNS
Expand All @@ -24,6 +25,10 @@
class Normalizer(NormalizerProtocol):
"""This class includes functions for text normalization."""

# Non-left-joining letters (isolated form) in Persian/Arabic
# These letters don't connect to the next letter, so ZWNJ is not needed before suffixes
_NON_LEFT_JOINING_LETTERS: Final[tuple[str]] = ("ا", "د", "ذ", "ر", "ز", "ژ", "و")

def __init__(
self,
correct_spacing: bool = True,
Expand Down Expand Up @@ -362,6 +367,7 @@ def token_spacing(self, tokens: list[str]) -> list[str]:
result: list[str] = []
for t, token in enumerate(tokens):
joined = False
use_zwnj = True

if result:
token_pair = result[-1] + "‌" + token
Expand All @@ -380,9 +386,16 @@ def token_spacing(self, tokens: list[str]) -> list[str]:

elif self._words and token in SUFFIXES and result[-1] in self._words:
joined = True
# Only use ZWNJ if the last character is left-joining
# Non-left-joining letters (ا, د, ذ, ر, ز, ژ, و) already create a visual gap
if result[-1] and result[-1][-1] in self._NON_LEFT_JOINING_LETTERS:
use_zwnj = False

if joined:
result[-1] = token_pair
if use_zwnj:
result[-1] = result[-1] + "‌" + token
else:
result[-1] = result[-1] + token
else:
result.append(token)

Expand Down
2 changes: 2 additions & 0 deletions tests/test_normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ def test_seperate_mi(self:"TestNormazlier", normalizer, text, expected):
(["کتاب", "ها"], ["کتاب‌ها"]),
(["کتاب", "های"], ["کتاب‌های"]),
(["کتاب", "هایی"], ["کتاب‌هایی"]),
# Issue #367: Non-left-joining letters should not have ZWNJ before suffixes
(["بندر", "ها"], ["بندرها"]), # د is non-left-joining
(["او", "می", "رود"], ["او", "می‌رود"]),
(["ماه", "می", "سال", "جدید"], ["ماه", "می", "سال", "جدید"]),
(["اخلال", "گر"], ["اخلال‌گر"]),
Expand Down