arafix
Recover broken Arabic text from PDFs — diagnose first, then apply a graded repair ladder. Not a single hammer, and not “just run OCR.”
| Core | Zero dependencies (stdlib only) for text stages 0–2 |
pip install "arafix[pdf]" — geometric extract + Arabic repair |
|
| Layout | Multi-column RTL, headers/footers, simple tables (layout=auto) |
| Status | Alpha 0.8 — production-curious, still evolving |
Install
pip install arafix # text repair only
pip install "arafix[pdf]" # recommended — PDF extract
pip install "arafix[all]" # + fonttools (CMap / stage 3)
30-second start
from arafix import repair_text, extract_pdf
# Presentation-form garbage → readable Arabic
print(repair_text("\ufee3\ufeae\ufea3\ufe92\ufe8e").text) # مرحبا
# Native (not scanned) Arabic PDF
doc = extract_pdf("thesis.pdf")
print(doc.text)
print(doc.confidence, doc.pages[0].n_columns)
arafix diagnose thesis.pdf -v
arafix extract thesis.pdf -o out.txt
arafix extract paper.pdf --layout full -v --tables
What it fixes (and what it doesn’t)
| Symptom | Cause | Stage |
|---|---|---|
| Reversed letter order | Visual storage order | 2 |
Isolated Arabic glyphs (ﻣﺮﺣﺒﺎ) |
Presentation forms | 1 |
ال… mojibake |
UTF-8 read as Latin-1 | 0 |
المجالت / االنترنيت |
Lam-alef ligature broken before reorder | 1a→2→1b |
()مقدمة |
Engine bidi vs neutrals | geometric read |
| Two columns mixed | Line-joined gutters | layout (0.8) |
| Empty / PUA soup | Broken ToUnicode / scan | 3 / 4 (OCR not shipped) |
Philosophy: never invent characters; never “fix just in case”; every decision carries evidence and confidence.
Further reading: INTEGRATING.md · DEPLOY.md · CHANGELOG.md · RELEASING.md
Name note: other GitHub projects may also expose an
arafiximport. See the Arabic naming section and RELEASING.md. Publish promptly after configuring the PyPI publisher — a pending publisher does not reserve the name.
arafix — التوثيق العربي
استرجاع النص العربي من ملفات PDF المعطوبة. سلّمٌ من خمس درجات، لا مطرقةٌ واحدة.
⚠️ تنبيه تسمية — والقرار عاجل. الاسم
arafixمأخوذ فعلياً على GitHub بأربعة مستودعات، وأحدها (AraFix-V3.0) يوفّر حزمة بايثون عليا اسمهاarafixبالحرف. تثبيتهما معاً يكسر أحدهما — ومن يستوردarafixلا يدري أيّهما جاءه. الاسم على PyPI شاغرٌ بعدُ — لكنّ الناشر المعلَّق على PyPI لا يحجز الاسم، وإعادة التسمية قبل النشر أسلم منها بعده بمراتب. انظر التسمية والجيران وRELEASING.md.
المسألة
عندك ملف PDF عربي أصليّ — لا صورة ممسوحة، بل نصٌّ حقيقيّ مُصدَّر من Word. تفتحه فتقرؤه بلا عناء. تستخرجه ببايثون فيخرج:
| ما ترى | العلّة | الدرجة العلاجية |
|---|---|---|
ا ب ح ر م |
ترتيب بصريّ مخزَّن معكوساً | ٢ |
م ر ح ب ا متفرقة |
أشكال رسومية مطبوخة (U+FB50–FEFF) | ١ |
المتوسط |
موجيبيك — علّة أنبوبك لا علّة الملف | ٠ |
المجالت بدل المجلات |
رباط «ﻻ» فُكّ قبل إصلاح الاتجاه | ١أ+٢+١ب |
()مقدمة بدل (مقدمة) |
بِدي المحرّك يبعثر المحايدات | القراءة الهندسية |
نشُرت بدل نُشرت |
العَكس على المحارف لا على العناقيد | ٢ |
`` أو ????? |
خريطة ToUnicode تالفة | ٣ |
| لا شيء | لا طبقة نصية (ممسوح ضوئياً) | ٤ |
العلل خمس، والعلاجات خمسة، ولكلٍّ دواؤه. أكثر ما يُتداول من حلول يخلط بينها، فيطبّق دواء الثانية على الرابعة، ثم يستنتج أن «العربية مستحيلة في PDF».
تصحيحان لخرافتين شائعتين
❌ «الـ OCR هو الحل الأسرع والأدق للعربية.»
خطأ. OCR العربي آخر الدواء لا أوّله: أبطأ بمراتب، ويخطئ في الهمزة والتشكيل والأرقام، ويهدم بنية الجداول. لا تنزل إليه إلا حين تنعدم طبقة النص أصلاً (الدرجة ٤). ما دون ذلك يُحلّ بسطرٍ إلى عشرين.
❌ «الرباط ﻻ حرفان مثل fi في اللاتينية.»
خطأ، والفرق ليس تفصيلاً. رباط لام-ألف في العربية إلزاميّ لا اختياريّ: لا يوجد خطٌّ يرسم لاماً ثم ألفاً منفصلتين. فهو في ملف الـ PDF جليفٌ واحد. ومن فكّه إلى حرفين ثم عكس السطر، عكس الحرفين معه فصارت «لا» ← «ال». وهذا مصدر أشهر عطبٍ في استخراج العربية:
الانترنيت → االنترنيت المجلات → المجالت
الأطاريح → األطاريح الإجراء → اإلجراء
❌ «المشكلة في الحروف؛ فإن خرجت العربية سليمةً فقد نجوت.»
خطأ، وهو أخبث ما في الباب. الحروف أمتنُ ما في السطر، والترقيم أهشُّه.
المحايدات (( ) [ ] . ! ,) لا اتجاه لها في يونيكود، فيتنازعها ما حولها،
فتُخرج المحرّكاتُ عربيةً سليمةً وترقيماً مبعثراً:
(مقدمة الدراسة) → ()مقدمة الدراسة
الفقرة [أ-ج] هنا → ج[ هنا-الفقرة ]أ
ولاحظ أن ؟ و؛ تنجوان دائماً حيث تعطب ! و. — لأنهما عربيّتان
(صنف AL قويّ الاتجاه) لا محايدتين. من لا يقرأ العربية لا يرى العطب أصلاً.
❌ «
الميعني أن الـ CMap تالف.»
خطأ. هذا موجيبيك: بايتات UTF-8 فُكّت بـ Latin-1. الملف سليم، والعطب في
كودك أنت. علاجه .encode('latin-1').decode('utf-8'). أما الـ CMap
التالف فعلامته رموز PUA (U+E000–F8FF) أو خانات فارغة، وعلاجه شيء آخر
تماماً (الدرجة ٣).
التثبيت
# النواة (الدرجات ٠–٢): بلا أيّ تبعيّة — بايثون قياسيّ خالص
pip install arafix
# مع دعم PDF (مستحسن)
pip install "arafix[pdf]"
# كل شيء بما فيه الدرجة ٣
pip install "arafix[all]"
# جسر MarkItDown (إضافة PDF عربية + post-process)
pip install "arafix[markitdown]"
# من المصدر
git clone https://github.com/bio-colab/arafix
cd arafix && pip install -e ".[dev]" && pytest
الـ sdist يحمل الاختبارات والأمثلة عمداً: مَن حمّل المصدر يجب أن يستطيع
تشغيل pytest عليه فيتحقق بنفسه، لا أن يصدّق شهادتنا. وللنشر انظر
RELEASING.md.
قرارٌ مقصود: النواة بلا تبعيّات. الدرجات ٠–٢ تعمل في أيّ بيئة — Colab مقيّد، خادم بلا إنترنت، Lambda. التبعيّات كلها اختيارية.
جرّبها الآن (٣٠ ثانية، بلا ملفٍّ منك)
# ١) ولّد ملفاً معطوباً عمداً — يحاكي مُصدِّراً رديئاً حقيقياً
python examples/make_broken_pdf.py broken.pdf
# ٢) شخّص. لاحظ: هذا الأمر لا يكتب شيئاً، يريك فقط
arafix diagnose broken.pdf -v
# ٣) عالِج
arafix extract broken.pdf
المخرَج قبل وبعد:
─ ما تراه أدوات بايثون:
ﺩﺭﺍﺳﺔ ﻤﻘﺎﺭﻧﺔ ﻔﻲ ﺎﻟﺴﻴﺎﺳﺔ ﺎﻟﻌﺎﻣﺔ
ﻔﻲ ﻤﺠﻠﺔ ﻤﺤﻜﻤﺔ2024 ﻧﹹﺸﺮﺕ ﻬﺬﻩ ﺎﻟﺪﺭﺍﺳﺔ ﻌﺎﻡ
─ بعد arafix:
دراسة مقارنة في السياسة العامة
في مجلة محكمة2024 نُشرت هذه الدراسة عام
from arafix import repair_text
r = repair_text(broken_text)
r.text # النص بعد العلاج
r.diagnosis.summary() # 'presentation_forms، visual_order'
r.confidence # 0.94
[s.value for s in r.stages_applied] # ['hygiene', 'diagnose', 'normalize', 'reorder']
r.notes # لماذا فُعل كل شيء
from arafix import repair_blocks, fix_table, TextBlock
fix_table([["خلية معطوبة", "سليمة"], ["…", "…"]])
out = repair_blocks([
TextBlock(cell, id=f"r{i}c{j}", role="cell")
for i, row in enumerate(grid)
for j, cell in enumerate(row)
])
out.by_id()["r0c1"].text
بعد MarkItDown أو أيّ مستخرج
انظر INTEGRATING.md.
from arafix import fix_markitdown, fix_any
from markitdown import MarkItDown # اختياري
fixed = fix_markitdown(MarkItDown().convert("thesis.pdf"))
# أو: fix_any(open("paste.txt", encoding="utf-8").read())
from arafix import extract_pdf
doc = extract_pdf("thesis.pdf")
print(doc.text)
print(doc.confidence) # أدنى ثقة عبر الصفحات
for page in doc.pages: # كل صفحة تُشخَّص وحدها — عمداً
if page.repair.confidence < 0.7:
print(page.page_number, page.repair.diagnosis.summary())
from arafix import diagnose
d = diagnose(text)
d.defects # [PRESENTATION_FORMS, VISUAL_ORDER]
d.confidence_in(Defect.PRESENTATION_FORMS) # 1.0 ← شاهدٌ قاطع
d.confidence_in(Defect.VISUAL_ORDER) # 0.93 ← شاهدٌ ظنّيّ
d.confidence # 0.93 ← أضعف حلقة
for e in d.evidence:
print(e) # final_only_letters=+0.940 :: ة/ى في أول 47 كلمة مقابل آخر 3
ولاحظ أن الثقة مفصولة لكل علّة. الرقم الواحد يُخفي أن بعض شواهدنا قاطعة وبعضها ظنّيّ، فيظلم الأولى ويجمّل الثانية:
| نوع الشاهد | الثقة | لماذا |
|---|---|---|
| قاطع (نطاقٌ أو اختبارٌ جبريّ) | ١٫٠ دائماً | فحصُ نطاقٍ على ٥ محارف قاطعٌ كفحصه على ٥٠٠٠. حجمُ العيّنة لا دخل له. |
| ظنّيّ (الاتجاه) | بدرجة شاهده | |
| «سليم» — شهادةُ نفي | ٠٫٣ ← ٠٫٩ بحجم العيّنة | وحدَها يحكمها الحجم، إذ هي استدلالٌ بغياب الدليل. وسقفُها ٠٫٩ عمداً: غيابُ العلّة ليس برهانَ سلامة. |
لاحظ الشواهد. الفرق بين أداةٍ تقول «النص معكوس» وأداةٍ تقول «معكوس لأن ٩٤٪ من التاءات المربوطة وقعت أوّل الكلمة» هو الفرق بين أداةٍ تُصدَّق وأداةٍ تُستعمل على عمى.
الضبط
from arafix import PipelineConfig, NormalizeConfig, repair_text
cfg = PipelineConfig(
normalize=NormalizeConfig(
strip_diacritics=False, # افتراضيّ: الاسترجاع لا التعديل
unify_alef=True, # للبحث والفهرسة فقط
),
thresholds={"visual_order": 0.45}, # عتبة أشدّ
force_reorder=False,
)
r = repair_text(text, cfg)
from arafix import repair_lam_alef_transposition
r = repair_lam_alef_transposition("االنترنيت والمجالت")
r.text # 'الانترنيت والمجالت' ← القاطع أُصلح
r.fixed_decisive # 1
r.suspects_left # 1
r.suspect_words # ['المجالت'] ← مُبلَّغٌ عنه، غير مُخمَّن
# ومع معجم، يُحسم المُبهَم أيضاً:
repair_lam_alef_transposition("المجالت", lexicon=my_words).text # 'المجلات'
يمرّ هذا تلقائياً داخل repair_text / extract_pdf؛ ومرِّر
PipelineConfig(lexicon=...) لتزويده بالمعجم.
المعمار
النص الخام ◄── extractors/: القراءة الهندسية من تيار الرسم لا من بِدي المحرّك
│
├─ ٠ diagnose.py ◄── لا تعالج قبل أن تعرف. لا يكتب شيئاً.
│ ├── detect_mojibake اختبار جبريّ قاطع
│ ├── detect_presentation_forms عدّ نطاقيّ
│ ├── detect_pua عدّ نطاقيّ
│ └── detect_visual_order ٣ شواهد لغوية، تصويت مرجَّح
│
├─ ١أ normalize.py ◄── المفردات وحدها. ما يغيّر العنقود يُؤجَّل.
├─ ٢ order.py ◄── بصريّ ← منطقيّ، بحماية الأرقام واللاتينية
├─ ١ب normalize.py ◄── الرباطات والتشكيل الفاصل — بعد استقرار الترتيب
├─ ⚕ lamalef.py ◄── ترقيع عطبٍ وَرِثناه من أداةٍ أخرى
├─ ٣ cmap.py ◄── إعادة بناء الخريطة من الخط المضمَّن
└─ ٤ OCR ◄── آخر الدواء (لم يُنفَّذ بعد)
القرارات المعمارية، ولماذا اتُّخذت
١. كل جدول يونيكود مُولَّد، لا مكتوب بيد.
٧٣١ مدخلةً مشتقّةً من unicodedata — لا خطأ مطبعياً ممكناً، وتتحدّث مع
نسخة يونيكود تلقائياً. الاستثناءات وحدها يدوية، وكلٌّ منها مُبرَّرٌ في
تعليقٍ إلى جانبه.
٢. تطبيعٌ مُوجَّه لا NFKC.
NFKC يحلّ المشكلة ويحلّ معها عشرين لم تطلبها: يقلب R² إلى R2،
وfile إلى file، و① إلى 1. في بحثٍ أكاديميّ فيه رموز رياضية، هذا
تخريبٌ صامت. فنحن نطبّع نطاق الأشكال العربية وحده.
٣. لا مرحلة تُرجع نصاً عارياً. كلٌّ تُرجع كائناً يحمل النص ومعه سببَ ما فعلت ودرجةَ ثقتها. القرار للمستعمل، والمكتبة قابلة للتدقيق.
٤. لا درجةَ تُطبَّق بلا شاهد.
المكتبة لا تعالج «احتياطاً». عكسُ نصٍّ سليمٍ تخريبٌ بأيدينا. وأهمّ
اختبارٍ في الحزمة اسمه test_does_not_touch_healthy_text.
٥. التطبيع مُشطَّرٌ حول الاتجاه: ١أ ← ٢ ← ١ب. هذا القرار كُتب أوّلاً «التطبيع قبل الاتجاه»، وكان نصفَ صواب. فالتطبيع الكامل قبل الاتجاه يفكّ «ﻻ» إلى حرفين، ثم يعكسهما العكسُ إلى «ال». فصار: تُطبَّع المفردات (فتنكشف التاء المربوطة لكاشف الاتجاه)، ويبقى الرباط ذرّةً، ثم يُعكس، ثم يُفكّ الرباط. الدرجة ١ تفتح عين الدرجة ٢ ولا تسلّمها سكيناً.
٥ب. معيارُ التأجيل تغيُّرُ بنية العنقود، لا طولُ التفكيك.
يُؤجَّل صنفان: الرباطات (محرفٌ يصير محرفين)، وأشكال التشكيل الفاصلة
U+FE70–FE7F (محرفٌ فئتُه Lo يصير علامةً لاصقة Mn). كلاهما يغيّر
وحدةَ العكس، فتطبيعُهما المبكر يهدم ما بعده. ومعيارُ الطول وحده يُعمي عن
الثاني: تفكيك U+FE79 هو [كشيدة + ضمّة]، ونحن نطرح الكشيدة فيعود الطول
واحداً فيبدو بريئاً. فالفئةُ تفضح ما لا يفضحه الطول.
٥ج. الكاشف يقرأ طبقتين، لأن التطبيع يفقأ عيناً وهو يفتح أخرى.
التاء المربوطة لا تُرى إلا بعد التطبيع، وصيغُ الوصل لا تُرى إلا قبله.
فيأخذ detect_visual_order النصّ المطبَّع ومعه الأصل الرسوميّ
(shaped_source)، فيشهد كلٌّ من طبقته.
٥د. هويّة الوصل برهانٌ لا أمارة.
في العربية: joins_forward(a) == joins_backward(b) لكل حرفين متجاورين —
لا تتخلّف أبداً في نصٍّ منطقيّ. فخرقُها مرّةً واحدة يُثبت الانعكاس.
شاهدٌ لا تماثليّ: يدحض ولا يُزكّي. (كان الفحص أوّلاً على طرفَي الكلمة
وحدهما، فأفلتت منه كلماتٌ كـ«الإجراء» طرفاها منفصلان.)
٦. text[::-1] خطأ، لا اختصار — لثلاثة أسباب لا سبب.
(أ) الأرقام واللاتينية LTR في الحالين، فالعكس يفسد 2024 فتصير 4202
وGDP_2024 تصير 2024_GDP. (ب) الأقواس مِرآتية: جليفُ أقصى اليسار
في سطرٍ عربيّ هو ( وإن كان المحرف المنطقيّ هناك )، فبلا مرآةٍ تخرج
)مقدمة(. (ج) وحدةُ العكس العنقودُ لا المحرف: التشكيل عرضُه صفر
ويشترك في موضع حرفه، فعكسُ المحارف يُلصقه بالجار (أولاً ← أوًلا).
٧. القراءة من تيار الرسم، لا من بِدي المحرّك.
قياسٌ لا رأي: على ١٢ سطراً فيها ترقيم، أخفق مسار get_text() في ٩
وأخفق المسار الهندسيّ في صفر. ونقرأ بـ get_texttrace لا rawdict،
وهذا شرط: rawdict يعيد ترتيب محارفه ببِدي MuPDF قبل تسليمها، فيهدم
الربط الذي جئنا نستشهد به.
٨. ولكلٍّ من ربط العنقود وترتيبه شاهدٌ مختلف — والخلطُ بينهما فخّ.
الربط (أيّ علامةٍ لأيّ حرف؟) من التيار: الهندسة تكذب هنا، إذ
العلامة عرضُها صفر فتُرسَم عند القلم بعد أن تجاوز حرفَها، فـ x عندها
يساوي x للحرف التالي. الترتيب (أيّ عنقودٍ قبل أيّ؟) من
الهندسة: التيار قد يكون بصرياً، وx وحده يقول أين وقع كلُّ شيء.
٩. لا نكتب قارئ PDF.
كتابته عملُ سنين، وموجودٌ منه ما يكفي. كل محرّك يُغلَّف خلف Extractor
واحد، فتبديله سطرٌ وإضافةُ جديدٍ ملفٌّ واحد.
١٠. cid1234 لا يُفكّ.
رقمٌ داخليّ للخط بلا دلالة. من يفكّه يخترع من عنده — وهذا خطٌّ أحمر:
المكتبة تعجز صراحةً ولا تخترع أبداً.
التوسيع
محرّك استخراج جديد
from arafix.extractors import Extractor, RawPage, register
@register
class PdfMinerExtractor(Extractor):
name = "pdfminer"
@classmethod
def available(cls) -> bool:
try:
import pdfminer; return True
except ImportError:
return False
def pages(self, path):
from pdfminer.high_level import extract_pages
...
yield RawPage(number=i, text=text)
def font_bytes(self, path):
return {}
سطرٌ واحد (@register)، ولا يُمسّ شيءٌ آخر في المكتبة. ثم:
extract_pdf(path, PipelineConfig(extractor="pdfminer")).
كاشف علّة جديد
١. أضف عضواً إلى Defect في types.py.
٢. اكتب دالةً في diagnose.py تُرجع (score, Evidence).
٣. نادها داخل diagnose() مع عتبةٍ في DEFAULT_THRESHOLDS.
٤. اكتب اختباراً يوثّق القرار لا السطر.
شاهد اتجاه جديد
أضف دالة _signal_* تُرجع (score, detail) في [-1, 1]، وسجّل وزنها في
_ORDER_WEIGHTS. التصويت يُعاد تطبيعه على الشواهد الحاضرة وحدها، فغياب
شاهدٍ لا يُميّع النتيجة.
خارطة الطريق
- الدرجة ٠ — التشخيص بشواهد
- الدرجة ١ — التطبيع المُوجَّه
- الدرجة ٢ — الاتجاه بحماية LTR
- الدرجة ٣ — الخريطة من
cmapوأسماء الجليفات - الرباطات — تشطير التطبيع حول الاتجاه + ترقيع رجعيّ (0.2.0)
- المحايدات — قراءة هندسية، مرآة الأقواس، عكسٌ عنقوديّ (0.3.0)
- معجم عربيّ مدمج يحسم مواضع «ال» الوسطية بلا تدخّل
- الدرجة ٣+ — مطابقة الشكل (perceptual hash للجليف)
- الدرجة ٤ — غلاف OCR
- استخراج بنيويّ (جداول، حواشٍ، أعمدة)
- محرّكات: pdfminer، pypdf، pdftotext
- القياس — CER/WER ومقارنةُ المسارات على ملفك (0.4.0)
- نظافة الاستخراج — NBSP / soft-hyphen (0.7.0)
-
repair_blocks/ جداول — إصلاحٌ مستقلّ لكل خلية (0.7.0) - معجم الوثيقة الداخليّ يحسم «المجالت» عبر الصفحات (0.7.0)
- جسر MarkItDown — plugin +
fix_markitdown(0.7.0) - أعمدة RTL + ترويسة/تذييل + جداول بنيوية (0.8.0)
- حزمة ملفات مرجعية (corpus) عامّة لقياس الانحدار
- حسمُ «المجالت» بنموذج n-gram على مستوى المحرف (اقتباساً من CAMeL)
- إخراج PDF قابل للبحث بالنصّ المصحَّح
الدرجة ٣+ فكرتها: ارسم كل جليفٍ من الخط المضمَّن، وقارنه بصرياً بمرجعٍ لكل حرفٍ عربيّ. هذا OCR على مستوى الجليف لا الصفحة: مساحة البحث ٣٦ حرفاً × ٤ أشكال، لا لغةٌ كاملة. أدقّ بمراتب وأسرع.
الاختبارات
pytest # ~١٨٠ اختباراً (+ hygiene/blocks/plugin)
pytest --doctest-modules src/arafix
ruff check src tests
كل اختبارٍ يوثّق قراراً لا سطر كود. فإن كسرته يوماً، عرفت من اسمه أيّ قرارٍ كسرت ولماذا اتُّخذ أوّلاً.
حدودٌ مُعلَنة
بصراحةٍ تسبق الاستعمال:
- الدرجة ٤ (OCR) غير منفَّذة، ولا حزمةَ
arafix[ocr]. المكتبة تكشف الحاجة وتقولها ولا تدّعي. وكان هناكextraباسمocrيجرّpytesseractبلا كودٍ يستعمله — وعدٌ بلا سند، فحُذف. لا نبيع تبعيّةً مقابل نيّة. - الدرجة ٣ تعجز عن الخطوط CID ذات الأسماء العديمة الدلالة. تُصرّح بالعجز (تغطية منخفضة) ولا تخترع.
- كاشف الاتجاه احتماليّ لا حتميّ — ولذلك يُرجع درجةً وشواهد لا حكماً.
- الجداول والأعمدة خارج النطاق حالياً؛ الاستخراج خطّيّ.
- ترقيع لام-ألف الموروث ناقصٌ بطبعه. يُصلح القاطع (ألفان متجاورتان:
االنترنيت) يقيناً، ويُبلّغ عن المُبهَم (المجالت) ولا يخمّنه — إذ لا قاعدةَ إملائية تميّزه عن «أفعالهم». مرِّرlexicon=ليُحسم. والوقاية وحدها تامّة: ما تعالجه المكتبة من أوّله يخرج سليماً بلا معجم. - الأعمدة والجداول مدعومة منذ 0.8.0 عبر
layout="auto"|"columns"|"full"(ميزاب أفقي + RTL). الكشف إحصائيّ: صفحات بثلاثة أعمدة متداخلة أو جداول بلا فجوات واضحة قد تحتاج ضبطLayoutConfig. - لم تُختبر إلا على ملفاتٍ مولَّدة، وكلُّ رقمٍ في هذا الملف مقيسٌ
عليها. وهو نصفُ حجّة.
arafix eval --compareموجودٌ لتُتمّها أنت على ملفاتك. وإن كسرَتها ملفاتُك، افتح issue بها — هذا أنفع إسهامٍ ممكن: عطبُ الرباط الذي أصلحته 0.2.0، وأعطابُ الترقيم الثلاثة في 0.3.0، كلُّها وصلت من مستعملٍ فعل ذلك بالضبط.
المساهمة
الأنفع بالترتيب: (١) ملفات تكسرها، (٢) محرّكات جديدة، (٣) شواهد اتجاه أقوى، (٤) الدرجة ٣+.
الترخيص
MIT — انظر LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file arafix-0.8.0.tar.gz.
File metadata
- Download URL: arafix-0.8.0.tar.gz
- Upload date:
- Size: 110.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e25f6d0942da7e8a4edbee100d9a36df3faf3e48fd550532f80cd7fff436b24
|
|
| MD5 |
f9be8b5110c8f5431fdc67f80f676f5b
|
|
| BLAKE2b-256 |
e5b45f8ecda9e0fa00d9d6efef943da2b8a5e6f099e0835d0467248a15ec5ac1
|
Provenance
The following attestation bundles were made for arafix-0.8.0.tar.gz:
Publisher:
publish.yml on bio-colab/arafix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
arafix-0.8.0.tar.gz -
Subject digest:
4e25f6d0942da7e8a4edbee100d9a36df3faf3e48fd550532f80cd7fff436b24 - Sigstore transparency entry: 2300529238
- Sigstore integration time:
-
Permalink:
bio-colab/arafix@b56e9a01c645b572b2fa842c44c9bc8f400eb2fb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/bio-colab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b56e9a01c645b572b2fa842c44c9bc8f400eb2fb -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file arafix-0.8.0-py3-none-any.whl.
File metadata
- Download URL: arafix-0.8.0-py3-none-any.whl
- Upload date:
- Size: 76.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc6a92bffbd58e03d48c1180bae801801ab6a270bc502fa13db46b6af227eafa
|
|
| MD5 |
8d1c607d0cc6aa7d17c603f984a51793
|
|
| BLAKE2b-256 |
284376e3c252a9059068ec79f5e6377c7c71df8b15fda60650500b86f6e11826
|
Provenance
The following attestation bundles were made for arafix-0.8.0-py3-none-any.whl:
Publisher:
publish.yml on bio-colab/arafix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
arafix-0.8.0-py3-none-any.whl -
Subject digest:
bc6a92bffbd58e03d48c1180bae801801ab6a270bc502fa13db46b6af227eafa - Sigstore transparency entry: 2300529264
- Sigstore integration time:
-
Permalink:
bio-colab/arafix@b56e9a01c645b572b2fa842c44c9bc8f400eb2fb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/bio-colab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b56e9a01c645b572b2fa842c44c9bc8f400eb2fb -
Trigger Event:
workflow_dispatch
-
Statement type: