Skip to main content

Pixel-accurate word coordinates for every word in the Quran (Madani mushaf)

Project description

Quran Word Coordinates

Pixel-accurate word coordinates for every word in the Quran (Madani mushaf). Maps each of the 77,320 words across 604 pages to its exact bounding box on the page image.

Install

Python

pip install qurancoor

JavaScript / TypeScript

npm install quran-word-coords

Quick Start

Python

from qurancoor import get_page, get_word, find_word_at, get_ayah, scale_coords

# Get all word coordinates on page 7
coords = get_page(7)
# => {"2:38:1": {"h": {"x": 818, "y": 23, "w": 61, "h": 68}, ...}, ...}

# Get a specific word: Sura 2, Ayah 255 (Ayat Al-Kursi), Word 1
word = get_word(2, 255, 1)
print(word["h"])  # {"x": ..., "y": ..., "w": ..., "h": ...}

# Find which word is at pixel (820, 40) on page 7
location = find_word_at(7, 820, 40)
# => "2:38:1"

# Get all words in Al-Fatiha, Ayah 1
words = get_ayah(1, 1)

# Scale to a different display size
scaled = scale_coords(word["h"], target_width=1800, target_height=2874)

JavaScript / TypeScript

import { getPage, getWord, findWordAt, getAyah, scaleBox } from 'quran-word-coords';

// Get all word coordinates on page 7
const coords = getPage(7);

// Get a specific word
const word = getWord(2, 255, 1);
console.log(word?.h); // { x: ..., y: ..., w: ..., h: ... }

// Hit-test: find word at pixel position
const location = findWordAt(7, 820, 40); // => "2:38:1"

// Get all words in an ayah
const ayah = getAyah(1, 1);

// Scale coordinates
const scaled = scaleBox(word!.h, 1800, 2874);

API Reference

Function Python npm Description
Get page coords get_page(7) getPage(7) All word boxes on a page (1-604)
Get word coords get_word(2, 255, 1) getWord(2, 255, 1) Specific word by sura:ayah:word
Hit-test find_word_at(7, 820, 40) findWordAt(7, 820, 40) Which word is at (x,y)?
Get ayah words get_ayah(2, 255) getAyah(2, 255) All words in an ayah
Scale coords scale_coords(box, w, h) scaleBox(box, w, h) Adapt to different image sizes
Word count word_count(7) wordCount(7) Number of words on a page
All locations all_locations(7) allLocations(7) Sorted word keys on a page
Free memory clear_cache() clearCache() Release cached data

Coordinate Format

Each word has up to 3 coordinate boxes, all in pixels relative to the page image (900 x 1437):

{
  "2:38:1": {
    "h": { "x": 818, "y": 23, "w": 61, "h": 68 },
    "p": { "x": 818, "y": 0,  "w": 61, "h": 23 },
    "o": { "x": 0,   "y": 23, "w": 39, "h": 68 }
  }
}
Box Name Purpose
h Highlight Tight bounding box around the word ink
p Padding Space above the text line (for tooltips/popovers)
o Origin Left margin area (for line markers)

Key format: "sura:ayah:word" — e.g., "2:38:1" = Sura 2 (Al-Baqarah), Ayah 38, Word 1.

Practical Use Cases

  1. Word-by-word highlighting during audio recitation — map audio timestamps to word coordinates
  2. Tap-to-show tafsir — hit-test user taps against word boxes on mushaf images
  3. Visual search results — highlight found words directly on mushaf pages
  4. Tajweed overlay — color-code words with tajweed rules at exact positions
  5. Qira'at (variant readings) — mark words with reading differences
  6. Word frequency tools — tap a word to see all its occurrences across the Quran

How Word Positioning Works

The system achieves pixel-accurate coordinates through a 5-step pipeline:

Step 1: Font Metric Analysis

Each page uses a dedicated QCF font (QCF_P001.TTF ... QCF_P604.TTF) where every word is a single glyph. The system extracts the advance width of each glyph from the font's hmtx table to determine proportional spacing.

Step 2: Image Line Detection

Horizontal projection analysis on the grayscale page image identifies text line bands — consecutive rows with ink above a threshold. Standard pages have 15 lines; sura opening pages have 8.

Step 3: Glyph Database Lookup

From quran_glyphs.db (built from quran.com-images), the system retrieves ALL glyphs on each line — words, ayah markers, and waqf marks. Non-word elements occupy physical space and must be accounted for.

Step 4: Proportional Cutting with Gap Snapping

The core algorithm:

  1. Proportional cuts from font advance widths give expected boundary positions
  2. Gap detection scans actual image pixels for vertical whitespace columns
  3. Snap to gaps aligns each cut to the nearest real gap using a scoring function:
    score = gap_width * 2.0 - distance_from_expected * 0.5
    
  4. Minimum width enforcement prevents collapsed boxes (< 25% expected width)

Step 5: Mushaf JSON Alignment

The quran.com-images database numbers waqf marks as word positions, but the mushaf JSON skips them — causing position misalignment. The system matches word boxes to mushaf words by sequential order within each line, not by position numbers, ensuring every word maps correctly.


Repository Structure

qurancoor/
  pyproject.toml              # Python package config
  src/qurancoor/              # Python package source
    __init__.py               # Library API
    data/                     # 604 coordinate JSON files
  npm/                        # npm package
    package.json
    src/index.ts              # TypeScript API
    data/coords.json          # Combined coordinate data
  tools/                      # Generation & development tools
    generate_coords.py        # Coordinate extraction pipeline
    build_word_freq.py        # Word frequency database builder
    server.py                 # Web viewer/editor (FastAPI)
  data/
    coords/                   # Alternative coordinate data
    pages/farsh/              # Qira'at variant readings
  quran.com-images/           # Submodule: fonts, SQL data
  output/                     # Raw generated coordinates

Building from Source

These steps are only needed if you want to regenerate the coordinate data.

Prerequisites

pip install numpy Pillow fonttools fastapi uvicorn

You also need mushaf page images (900x1437 PNG) in images/ and the quran.com-images submodule.

Generate Coordinates

# Build glyph database
python3 tools/generate_coords.py --build-db -q quran.com-images

# Generate all page coordinates
python3 tools/generate_coords.py -b . -q quran.com-images -o output --all

# Single page with debug overlay
python3 tools/generate_coords.py -b . -q quran.com-images -o output --page 7 --debug

Build Word Frequency Database

python3 tools/build_word_freq.py --mushaf-dir ./mushaf --db word_freq.db

Launch Viewer/Editor

python3 tools/server.py --images-dir ./images --json-dir ./output --mushaf-dir ./mushaf --port 8003

License

MIT. The mushaf images and quran.com-images data have their own licenses — see quran.com-images.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qurancoor-1.0.0.tar.gz (1.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qurancoor-1.0.0-py3-none-any.whl (1.6 MB view details)

Uploaded Python 3

File details

Details for the file qurancoor-1.0.0.tar.gz.

File metadata

  • Download URL: qurancoor-1.0.0.tar.gz
  • Upload date:
  • Size: 1.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for qurancoor-1.0.0.tar.gz
Algorithm Hash digest
SHA256 2dd7265e3c1da900f131115abdec8283ef7fe7401d562e91c0211505d2f53521
MD5 a19c99e0a1a4d36e7586b0b679a5a699
BLAKE2b-256 43a4fff29ea20ba0beaf09ea18c63fcef5f1ad0839abbed47a3c3a2f542171fe

See more details on using hashes here.

File details

Details for the file qurancoor-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: qurancoor-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for qurancoor-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a70c3584eae18a29cfe27a0c3e5e9483a3150e3c712f0c7f4ae133c56c5e149b
MD5 97137b0144f1a1daf0e056b070f9a7e9
BLAKE2b-256 e84693a9d8c744c9a8de05daed2341434cd11e8244783a5b7e7c03410e7dd6bb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page