Tutorial 2: Mushaf Layout End-to-End

This tutorial is for users who want to render page-accurate mushaf layouts from downloaded QUL data.

1) What This Resource Is

Mushaf Layout resources provide page-structured layout data for Quran pages.

In practice, this includes page lines and word ranges you can use to render page-faithful mushaf views.

Primary category:

2) When to Use It

Use mushaf layout data when you are building:

  • Page-by-page mushaf readers
  • Navigation by page number (instead of only surah/ayah)
  • Memorization or classroom tools that depend on printed page structure

Why Mushaf Layout Is Different (and Helpful)

The Help sample code and preview on a detail page (for example https://qul.tarteel.ai/resources/mushaf-layout/12) show a key difference:

  • mushaf-layout is a rendering-structure resource, not only a content resource.
  • It tells your app how to render a page (line_number, line_type, is_centered, first_word_id, last_word_id).
  • Most other resources (recitation, translation, tafsir, etc.) mostly give content keyed by ayah/word, but not page geometry.

Why this is useful:

  • You can recreate a printed mushaf page layout more accurately.
  • You can support page-first navigation and memorization workflows.
  • You can combine layout + script + font consistently, instead of hardcoding line templates in app code.

3) How to Get Your First Example Resource

  1. Open https://qul.tarteel.ai/resources/mushaf-layout.
  2. Keep the default listing order and open the first published card.
  3. Confirm the resource detail page includes:
    • Mushaf Page Preview tab
    • Help tab
  4. Confirm available download formats shown on the page (commonly images, sqlite, docx).

This keeps onboarding concrete without depending on a fixed resource ID.

4) What the Preview Shows (Website-Aligned)

On the mushaf layout detail page, preview helps you validate page rendering behavior before download:

  • Mushaf Page Preview tab:
    • Jump to page selector
    • Previous/next page navigation
    • Rendered page output with line and word structure
  • Help tab:
    • Required data to render a page (layout + script + font)
    • pages table schema (for line mapping)
    • words table schema expectations (for word ranges)
    • Sample rendering logic

Practical meaning:

  • pages table controls line structure for each page.
  • first_word_id/last_word_id ranges map into script words for line rendering.

5) Download and Use (Step-by-Step)

  1. Download the selected mushaf layout package (for example sqlite and related assets).
  2. Inspect layout records:
    • page_number
    • line_number
    • line_type
    • is_centered
    • first_word_id, last_word_id
    • surah_number (when relevant)
  3. Load matching Quran script word data (word-by-word format).
  4. For each page line:
    • If line_type is surah_name, render surah heading line.
    • If line_type is ayah, render words in first_word_id..last_word_id.
    • If line_type is basmallah, render basmallah line.
  5. Apply alignment using is_centered.
  6. Validate with at least three pages (start, middle, end) to catch mapping issues.

Starter integration snippet (JavaScript):

JavaScript
// Select all lines for a single page and keep display order stable.
const linesForPage = (pagesTableRows, pageNumber) =>
  pagesTableRows
    .filter((row) => row.page_number === pageNumber)
    .sort((a, b) => a.line_number - b.line_number);

// Convert a word ID range into one display string.
const getWordsInRange = (wordsByIndex, firstWordId, lastWordId) => {
  const result = [];
  for (let id = firstWordId; id <= lastWordId; id += 1) {
    if (wordsByIndex[id]) result.push(wordsByIndex[id].text);
  }
  return result.join(" ");
};

// Render line text by line type rules.
const renderLineText = (line, wordsByIndex, surahNameByNumber) => {
  if (line.line_type === "surah_name") return surahNameByNumber[line.surah_number] || "";
  if (line.line_type === "basmallah") return "﷽";
  if (line.line_type === "ayah") return getWordsInRange(wordsByIndex, line.first_word_id, line.last_word_id);
  return "";
};

6) Real-World Example: Render One Mushaf Page

Goal:

  • User opens page 1 and sees line-accurate mushaf rendering.

Inputs:

  • Mushaf Layout package (line mapping)
  • Quran Script package (word text)
  • Surah names metadata

Processing:

  1. User selects page number.
  2. App loads all lines for that page from layout data.
  3. App resolves words for each ayah line using word ID ranges.
  4. App applies centered/justified alignment based on is_centered.
  5. UI renders all lines in page order.

Expected output:

  • Page structure matches expected mushaf layout.
  • Surah name and ayah lines render in correct order (with basmallah lines when present in layout data).
  • Page navigation remains stable across adjacent pages.

Interactive preview (temporary sandbox):

You can edit this code for testing. Edits are not saved and may not persist after refresh.

JavaScript Playground
Editor
Preview

7) Common Mistakes to Avoid

  • Joining layout lines to words with wrong word ID field.
  • Ignoring line_type and rendering every line as ayah text.
  • Ignoring is_centered, which changes page appearance.
  • Validating only page 1 and skipping middle/end page checks.
  • Mixing incompatible script/font with selected layout package.

8) When to Request Updates or Changes

Open an issue if you find:

  • Incorrect line-to-word mapping on a page
  • Missing lines or broken page navigation
  • Download package inconsistencies (images, sqlite, docx, metadata)
  • Layout metadata that conflicts with preview behavior

Issue tracker:

Related Docs