@quran.ws/tajwid-annotations 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,35 @@
1
+ Tajweed Annotations (`@quran.ws/tajwid-annotations`)
2
+ Copyright (c) 2026 Quranpedia
3
+
4
+ This work is licensed under the Creative Commons Attribution 4.0 International
5
+ License (CC BY 4.0).
6
+
7
+ You are free to:
8
+
9
+ - Share — copy and redistribute the material in any medium or format
10
+ - Adapt — remix, transform, and build upon the material for any purpose,
11
+ even commercially
12
+
13
+ Under the following terms:
14
+
15
+ - Attribution — You must give appropriate credit, provide a link to the
16
+ license, and indicate if changes were made.
17
+
18
+ Full license text: https://creativecommons.org/licenses/by/4.0/legalcode
19
+
20
+ ---
21
+
22
+ ATTRIBUTION
23
+
24
+ When redistributing this corpus or a derivative of it, credit:
25
+
26
+ Tajweed Rule Corpus, Quranpedia — https://github.com/quranpedia/tajweed-engine
27
+
28
+ ---
29
+
30
+ A NOTE ON MODIFICATION
31
+
32
+ CC BY 4.0 permits modification. Please note that the rules in this corpus
33
+ encode positions attributed to named scholars. If you modify a rule's matching
34
+ behaviour, change its `source` attribution as well, so that a position is not
35
+ misattributed to a scholar who did not hold it.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # @quran.ws/tajwid-annotations
2
+
3
+ Precomputed tajweed annotations for the whole muṣḥaf: **147,255 spans** from
4
+ **164 rules**, across **6,235 of the 6,236 āyāt** of the riwāyah of
5
+ **Ḥafṣ ʿan ʿĀṣim**.
6
+
7
+ This package is data only. It has no dependencies and no code. It exists so an
8
+ app can render tajweed without shipping the engine — the engine that produced
9
+ it is [`@quran.ws/tajwid`](../core), running the corpus in
10
+ [`@quran.ws/tajwid-rules`](../rules).
11
+
12
+ ```bash
13
+ npm install @quran.ws/tajwid-annotations
14
+ ```
15
+
16
+ ```js
17
+ import annotations from '@quran.ws/tajwid-annotations'
18
+
19
+ annotations.corpusVersion // '0.4.2'
20
+ annotations.riwayah // 'hafs-an-asim'
21
+ annotations.edition.sha256 // 'b5d29736…' — the text these offsets are measured against
22
+ annotations.ruleIds.length // 164
23
+ ```
24
+
25
+ ## The shape
26
+
27
+ `spans` is keyed by `"surah:ayah"`, and each span is a packed triple:
28
+
29
+ ```js
30
+ annotations.spans['1:1']
31
+ // [[8, 10, 52], [17, 18, 22], [22, 25, 129], [30, 31, 22], [33, 36, 131]]
32
+ // ↑ ↑ ↑
33
+ // │ │ └─ index into annotations.ruleIds
34
+ // │ └───── end, half-open
35
+ // └───────── start — a code-point position, not a UTF-16 index
36
+ ```
37
+
38
+ ```js
39
+ const [start, end, rule] = annotations.spans['1:1'][0]
40
+ annotations.ruleIds[rule] // 'mutamathilain-idgham-kamil.23'
41
+ [...ayahText].slice(start, end).join('') // 'لل'
42
+ ```
43
+
44
+ Offsets are **code-point positions**, so index with `[...text]` or
45
+ `Array.from(text)`, never with `text.slice`. Arabic text at these positions is
46
+ full of combining marks, and a UTF-16 index will cut through one.
47
+
48
+ An āyah with no rulings is **omitted from `spans` entirely** rather than stored
49
+ as an empty array. Exactly one is: `20:1` (طه), whose disjoined letters the
50
+ corpus does not yet match. Treat a missing key as "no spans", not as an error.
51
+
52
+ ## What the offsets are measured against
53
+
54
+ Everything here is pinned to one text. `edition.sha256` is the digest of the
55
+ Uthmani Ḥafṣ edition in [`editions/`](../../editions), and `edition.ayahCount`
56
+ is 6,236.
57
+
58
+ **Check that digest before you use these offsets.** If your text differs from
59
+ that edition by a single code point — a different normalisation, a stripped
60
+ mark, a different waqf convention — every span after that point is wrong, and
61
+ nothing will tell you. If the digests do not match, run
62
+ [`@quran.ws/tajwid`](../core) over your own text instead of using this package.
63
+
64
+ ## No Quranic text is distributed here
65
+
66
+ This package contains offsets and rule ids. The text itself is not in it, by
67
+ design — bring your own, matching the digest above.
68
+
69
+ ## Licence
70
+
71
+ CC BY 4.0 — see [LICENSE](./LICENSE). The code in this repository is MIT; the
72
+ corpus and these annotations are not.
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@quran.ws/tajwid-annotations",
3
+ "version": "0.1.0",
4
+ "description": "Precomputed tajweed annotations for the whole mushaf: spans as code-point offsets, pinned to the digest of the text edition they were computed against.",
5
+ "license": "CC-BY-4.0",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "type": "module",
10
+ "main": "./uthmani-hafs.json",
11
+ "exports": {
12
+ ".": "./uthmani-hafs.json",
13
+ "./uthmani-hafs": "./uthmani-hafs.json"
14
+ },
15
+ "files": [
16
+ "*.json",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/quran-ws/quran-tajweed.git",
23
+ "directory": "packages/annotations"
24
+ },
25
+ "keywords": [
26
+ "quran",
27
+ "tajweed",
28
+ "annotations",
29
+ "uthmani",
30
+ "hafs"
31
+ ]
32
+ }