File size: 3,172 Bytes
6b2daa6
 
 
0078016
 
 
6b2daa6
501f57d
0078016
9236ab4
6b2daa6
0078016
 
0fe085c
 
 
 
0078016
0fe085c
0078016
a7647cc
7afec87
1a4e84b
 
0078016
1a4e84b
 
 
 
 
 
 
0078016
 
1a4e84b
 
 
 
 
0078016
1a4e84b
0078016
 
 
 
 
 
7afec87
0078016
 
 
 
 
 
5494d71
7afec87
c2e3785
0078016
 
 
 
c2e3785
7afec87
 
 
6b2daa6
7afec87
0078016
7afec87
a7647cc
7afec87
0078016
0fe085c
a7647cc
7afec87
0078016
 
0fe085c
0078016
0fe085c
 
 
 
 
a7647cc
0078016
9236ab4
0078016
6b2daa6
 
 
 
 
a7647cc
 
 
0078016
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import re
from helpers.cleaner import clean_text

# ----------- الأنماط (Regex Patterns) -----------

# المواد القانونية (مادة رقم ...)
ARTICLE_PATTERN = re.compile(
    r"^\s*ماد[ةه]\s*[\(\s]*([0-9]+)[\)\s]*",
    re.IGNORECASE | re.UNICODE
)

# الأقسام التقليدية (الباب / الفصل / القسم)
SECTION_PATTERN = re.compile(
    r'^\s*(الباب|الفصل|القسم)\s+([^\n]+)',
    re.IGNORECASE | re.UNICODE
)

# عبارة "أصدرنا القانون ..." داخل النص
LAW_ISSUE_PATTERN = re.compile(
    r'أصدرنا القانون\s+(.*?)(?=\s{2,}|$)',
    re.IGNORECASE | re.UNICODE
)

# ----------- تحويل الأرقام الهندية إلى عربية -----------

ARABIC_INDIC_DIGITS = str.maketrans("٠١٢٣٤٥٦٧٨٩", "0123456789")

def normalize_digits(s: str) -> str:
    if not isinstance(s, str):
        return ""
    return s.translate(ARABIC_INDIC_DIGITS)

# ----------- تنظيف النصوص -----------

def clean_text_block(text: str) -> str:
    if not isinstance(text, str):
        return ""
    return clean_text(normalize_digits(text.strip()))

# ----------- دوال التعرف على نوع النص -----------

def is_article(text: str) -> bool:
    """هل السطر عبارة عن مادة قانونية؟"""
    if not isinstance(text, str):
        return False
    text_norm = normalize_digits(text)
    return bool(ARTICLE_PATTERN.match(text_norm))

def is_section(text: str) -> bool:
    """هل السطر عنوان قسم (باب / فصل / قسم)؟"""
    if not isinstance(text, str):
        return False
    text_norm = normalize_digits(text)
    return bool(SECTION_PATTERN.match(text_norm))

def detect_line_type(text: str) -> str:
    """
    تحديد نوع السطر:
    - section → بداية قسم (باب/فصل/قسم) أو يحتوي «أصدرنا القانون»
    - article → بداية مادة
    - text    → نص عادي
    """
    if not isinstance(text, str) or not text.strip():
        return "text"

    text_norm = normalize_digits(text)

    if SECTION_PATTERN.match(text_norm):
        return "section"
    if ARTICLE_PATTERN.match(text_norm):
        return "article"
    if LAW_ISSUE_PATTERN.search(text_norm):
        return "section"
    return "text"

# ----------- استخراج تفاصيل القانون -----------

def extract_law_detail(text: str) -> str | None:
    """إرجاع التفاصيل التي تلي «أصدرنا القانون» مباشرة حتى نهاية السطر."""
    if not isinstance(text, str):
        return None
    m = LAW_ISSUE_PATTERN.search(text)
    return m.group(1).strip() if m else None

# ----------- استخراج رقم المادة -----------

def extract_article_number(text: str) -> int | None:
    """استخراج رقم المادة من النص إذا وجد."""
    if not isinstance(text, str):
        return None
    text_norm = normalize_digits(text)
    m = ARTICLE_PATTERN.match(text_norm)
    if m:
        digits = re.match(r'(\d+)', m.group(1))
        if digits:
            return int(digits.group(1))
    return None