Skip to content
View Syamjith-NK's full-sized avatar

Block or report Syamjith-NK

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Content in all repositories owned by your account will be closed.
Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
Syamjith-NK/README.md

Syamjith NK

Cinematographer and AI creative technologist in Abu Dhabi. I work where film craft meets applied AI, and I publish open evaluation of the Arabic tooling that production depends on.

Arabic breaks silently — three benchmarks

Each measures a failure that looks correct to anyone who does not read Arabic, which is exactly why it ships. All CC BY 4.0, with the test set, the scorer, the raw per-item results, and a plain statement of what the measurement does not establish.

finding
arnum-tts The same Arabic sentence with Arabic-Indic digits (٢٠٢٦) instead of Western (2026) drops from 73% to 7% intelligible on one engine. Another handles both at 80% — a missing normalisation step, not a hard problem.
arshape The arabic_reshaper + python-bidi recipe recommended in nearly every tutorial corrupts Arabic on any renderer that already shapes: 15/15 correct without it, 0/15 with it.
arpdf Reversed, ligature-mangled and space-collapsed are three distinct failure modes that a single pass/fail test collapses into one.

Datasets: huggingface.co/syamjithnk

The fix, not just the finding

The numeral failure above is now a package anyone can install:

pip install arabic-tts-frontend

arabic-tts-frontend · PyPI — numerals, dates, currency, times and percentages converted to spoken Arabic before the text reaches a TTS engine. MIT, zero dependencies. Re-measured against the released build on the same 45 sentences, same engine and scorer: Arabic-Indic digits 0/15 → 11/15. The scorer ships with it, so the figures can be re-derived rather than trusted, and the release notes state the run-to-run noise (±3) instead of quoting the overall number precisely.

Writing

The Arabic fix everyone recommends is now the bug — the get_display(reshape(...)) recipe is in 1,180 indexed files on GitHub and now renders Arabic backwards on matplotlib 3.11, silently. Why the shaping half is detectable and the reordering half is not, and what happened when I filed it upstream.

More at syamjith-nk.github.io.

Upstream

Filing the finding where the bug lives has reached far more people than publishing it ever did.

matplotlib — matplotlib 3.11 shapes Arabic itself, so the reshape+bidi recipe now runs twice and renders the label reversed. Nothing raises; it looks like Arabic to anyone who cannot read it. Measured as mean absolute pixel difference against a reference render: 7.75 for the raw logical string (antialiasing only), 76.28 pre-shaped. Three maintainers replied within two days, including the project lead — and one of them went and edited the StackOverflow answers to say the workaround is only for older versions. That is the widest-reaching outcome of any of this and it cost nothing but filing accurately. Docs PR #32263 is open.

The project lead proposed a fix I had not thought of — wrapping pre-processed text in Unicode LRO/PDF — and said he was not confident it was right for Arabic. I could check, so I did: across three fonts and nine strings it reads correctly in all of them, but does not always render identically, because the wrapped string draws the font's static presentation forms instead of the font's own shaping. That exchange is the argument for filing upstream rather than blogging first. He had the better fix; I had the only way to verify it.

Pillow — the same class of failure, different mechanism: Pillow's behaviour depends on whether it was built with Raqm, so the identical script produces correct text on one machine and broken text on another. On a Raqm-enabled build, 0 of 15 strings survive the recipe unchanged. The maintainer pushed back on my first draft for overclaiming a security angle. He was right, I dropped it, and the warning that remains is narrower and true.

python-arabic-reshaperissue #102 and PR #103, adding the PIL.features.check("raqm") test to the README so readers can tell which case they are in. Still unanswered.

The linter

arabic-lintpip install arabic-lint. Finds Arabic that was corrupted before it was stored, in JSON, localisation files, database exports and source. Zero dependencies, exit code 1 on a finding, so it drops into CI unchanged.

Detection is asymmetric, which is why this survived years of being copied: the shaping half leaves presentation-form codepoints that correctly authored Arabic never contains, so it is detectable — but the reordering half produces identical codepoints in a different order, so no general detector exists for it. And the damage is not cleanly reversible: lam-alef is one codepoint that decomposes to two, in logical order, while the text around it is in visual order. الإمارات goes 8 codepoints to 7, and the obvious NFKC repair turns السلام into السالم — a real but different word. The tool refuses to auto-fix those rather than guess.

How I work

In two of the three benchmarks the measurement contradicted the assumption I started with, and the write-ups say so. In arshape a pass/fail scorer reported a broken configuration as working; adding a middle band is what surfaced the real result. Designing a test that can prove you wrong is most of the work.

When I found four faults in my own scorer I published a documented correction with old-to-new figures rather than editing the numbers quietly.

Also

Brand and product films, VFX compositing, and AI-assisted image pipelines where the craft still governs the tool — a generated frame is judged on light, framing and rhythm like a photographed one.

syamjithnk.com · Abu Dhabi, GMT+4

Popular repositories Loading

  1. python-arabic-reshaper python-arabic-reshaper Public

    Forked from mpcabd/python-arabic-reshaper

    Reconstruct Arabic sentences to be used in applications that don't support Arabic

    Python

  2. arnum-tts arnum-tts Public

    Do numbers survive Arabic text-to-speech? An open, reproducible benchmark.

    Python

  3. arshape arshape Public

    Does Arabic survive text rendering? Shaping measured across fonts and rendering paths.

    Python

  4. arpdf arpdf Public

    Does Arabic survive a PDF round trip? Generation and extraction measured end to end.

    Python

  5. Syamjith-NK Syamjith-NK Public

    Profile README

  6. arabic-tts-frontend arabic-tts-frontend Public

    A text front-end for Arabic TTS: numerals, dates, currency and times converted to spoken Arabic before synthesis. Measured, zero dependencies.

    Python