Work & Evidence

What I have built, published and shipped

Cinematographer and AI creative technologist, based in Abu Dhabi. I work where film craft meets applied AI — and I publish what I find along the way, because most of it is not written down anywhere.

Updated 8 September 2026 · Abu Dhabi, United Arab Emirates

Upstream contributions

The findings below did not stay on this site. Where a finding was really a defect in a library, it was filed against that library — which is the only version of this work that anyone can verify without taking my word for it.

matplotlib — merged, 4 September 2026

matplotlib 3.11 shapes Arabic itself. That silently reverses the arabic_reshaper + python-bidi workaround that every tutorial, Stack Overflow answer and blog post still recommends — no error, no warning, just backwards labels on a chart nobody who reads Arabic was asked to check. The upgrade guide now tells 3.11 upgraders to remove that workaround.

To be precise about what was merged: the pull request is a documentation change, thirty lines. The work behind it was establishing that the reversal happens at all, that it is unconditional, and that the fix everyone recommends had become the bug. Three maintainers, including the project lead, engaged with the finding.

matplotlib #32263 · merged

Pillow — open, under review

The same class of defect one layer down: under the Raqm layout engine, pre-shaped Arabic is corrupted rather than drawn. Compounded by a trap that costs people days — whether Raqm is active is a property of the runtime, not of the Pillow version, so the identical wheel behaves differently on two machines depending on the host libraries. The patch warns at run time and documents that the layout engine is a build-time decision.

Pillow #9925 · open, checks passing

Stack Overflow — accepted answer, 8 September 2026

The canonical question on drawing right-to-left text in matplotlib has been read 15,226 times over thirteen years, and every answer on it predates 3.11 — so the most-read guidance on the internet now tells people to do the thing that reverses their charts. I answered it with the version boundary, the one code path that works on both sides of it, and the pixel measurement that separates “correct” from “reversed” (mean absolute difference 7.75 against 76.28). The asker accepted it.

To be precise about the scale: the answer scores 1. It is the reach of the question that matters here, not a vote count — and the correction now sits at the top of the page people actually land on.

Answer on “Matplotlib: Writing right-to-left text” · accepted

Published research

Open, reproducible evaluation of Arabic language technology — an area with enormous regional investment and very little practitioner-grade measurement.

Arabic numerals break text-to-speech, and almost nobody checks

The same Arabic sentence written with Western digits (2026) and Arabic-Indic digits (٢٠٢٦) produces wildly different speech. One engine reads the first at 73% intelligibility and the second at 7%; another handles both at 80%. The failure is invisible in evaluation because TTS demos contain no numbers — it surfaces in finished broadcast work, where a date or a price is spoken as noise.

Read the write-up · ArNum-TTS dataset · CC BY 4.0

The standard Arabic rendering recipe now corrupts Arabic

arabic_reshaper + python-bidi is the advice everywhere for drawing Arabic. On any modern text stack it produces مكب ابحرم where مرحبا بكم should be, because the renderer already did that work and it now happens twice. Measured across three fonts and four rendering paths, with the partial-rescue case that a single pass/fail would have hidden.

Read the write-up · ArShape dataset · CC BY 4.0

No PDF generator and extractor pair reads Arabic reliably

Naive generators store Arabic in logical order and laid-out ones store it visually; extractors then either re-apply the bidirectional algorithm or do not. The pairing is what decides the outcome, not the tool: LibreOffice into pypdf reads 5 of 5, LibreOffice into pdfminer reads 0 of 5 — same file, same text, opposite results.

Read the write-up · ArPDF dataset · CC BY 4.0

Shipped products

arabic-lint — on PyPI, 0.2.0

pip install arabic-lint. Finds Arabic that was corrupted before it was stored — the reshape-then-bidi recipe written back into JSON, localisation files and exports, where it survives every later render. Zero dependencies, exits non-zero, drops straight into CI.

It reports and deliberately never rewrites, because the obvious auto-fix is wrong: undoing the corruption round-trips exactly until the text contains a lam-alef ligature, and then السلام comes back as السالم — a real word, a different word, one that survives a human proofread.

0.2.0 adds a source check, which finds the code that will corrupt text at render time rather than the damage after the fact. The recipe appears in 3,168 indexed Python files, and reporting all of them would be worthless: whether it is a bug depends entirely on what draws the text. matplotlib 3.11 and Raqm-enabled Pillow shape and reorder for you, so pre-shaping reverses the string. ReportLab and non-Raqm Pillow do not, so pre-shaping is required. The check stays silent on the second group, on terminal output, and on a helper a script never calls.

I read six real projects to build it. Three were broken, and those are filed: a Discord bot whose helper still documents the pre-3.11 assumption, its sibling, a ComfyUI node built to render Persian, and an Arabic poetry dataset. Three were correct and were left alone. Deciding which is which is the work.

pypi.org/project/arabic-lint · MIT · the write-up

GenViz — iOS, on the App Store

A generative image product shipped end to end: application, authentication, billing, review and release. Approved and live.

Direct a Frame

A public interactive piece: visitors direct a single cinematic frame and watch it generated. Live on this site.

How I work

Two things run through all of it. First, the craft governs the tool: a generated frame is judged the way a photographed one is, on light, framing and rhythm, not on novelty. Second, I measure rather than assume — every published finding above began as an assumption I held confidently and the measurement contradicted, and every write-up says so plainly. That habit is why the results are worth citing.

There is a third habit, learned the hard way: publishing to your own site is not distribution. A finding only becomes useful when it is filed where the defect actually lives, in front of the people who maintain it — which is a far less comfortable place to be wrong, and the only reason any of the above is checkable.

Contact

Abu Dhabi, United Arab Emirates · Get in touch · huggingface.co/syamjithnk