quran-madina-html 0.1.2
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/.github/workflows/db_test.yml +26 -0
- package/.github/workflows/npm-grunt.yml +28 -0
- package/.github/workflows/pylint.yml +24 -0
- package/.vscode/extensions.json +5 -0
- package/.vscode/launch.json +16 -0
- package/.vscode/settings.json +30 -0
- package/DBs/Madina-Amiri-16px.json +114356 -0
- package/DBs/Madina-Amiri-24px.json +114356 -0
- package/DBs/Madina-Uthman-14px.json +114356 -0
- package/DBs/Madina-Uthman-16px.json +114356 -0
- package/Gruntfile.js +52 -0
- package/README.md +41 -0
- package/assets/fonts/AmiriQuran.woff2 +0 -0
- package/assets/fonts/AmiriQuranColored.woff2 +0 -0
- package/assets/fonts/UthmanTN_v2-0.woff2 +0 -0
- package/assets/fonts/hafs.woff2 +0 -0
- package/bower.json +16 -0
- package/build_all.py +30 -0
- package/build_db.py +269 -0
- package/db_test.py +32 -0
- package/demo/index.html +20 -0
- package/demo/x-tag-components.js +4784 -0
- package/dist/quran-madina-html-0.1.2.min.js +2 -0
- package/dist/quran-madina-html.js +4915 -0
- package/package.json +181 -0
- package/part_width_test.html +41 -0
- package/requirements.txt +4 -0
- package/src/quran-madina-html.css +10 -0
- package/src/quran-madina-html.js +131 -0
package/Gruntfile.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module.exports = function(grunt) {
|
|
2
|
+
|
|
3
|
+
grunt.initConfig({
|
|
4
|
+
pkg: grunt.file.readJSON('package.json'),
|
|
5
|
+
concat: {
|
|
6
|
+
options: {
|
|
7
|
+
separator: ';'
|
|
8
|
+
},
|
|
9
|
+
dist: {
|
|
10
|
+
src: ['src/**/*.js', 'demo/**/*.js'],
|
|
11
|
+
dest: 'dist/<%= pkg.name %>.js'
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
uglify: {
|
|
15
|
+
options: {
|
|
16
|
+
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
|
|
17
|
+
},
|
|
18
|
+
dist: {
|
|
19
|
+
files: {
|
|
20
|
+
'dist/<%= pkg.name %>-<%= pkg.version %>.min.js': ['<%= concat.dist.dest %>']
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
jshint: {
|
|
25
|
+
files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
|
|
26
|
+
options: {
|
|
27
|
+
// options here to override JSHint defaults
|
|
28
|
+
globals: {
|
|
29
|
+
jQuery: true,
|
|
30
|
+
console: true,
|
|
31
|
+
module: true,
|
|
32
|
+
document: true
|
|
33
|
+
},
|
|
34
|
+
esnext: true
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
watch: {
|
|
38
|
+
files: ['<%= jshint.files %>'],
|
|
39
|
+
tasks: ['jshint']
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
grunt.loadNpmTasks('grunt-contrib-uglify');
|
|
44
|
+
grunt.loadNpmTasks('grunt-contrib-jshint');
|
|
45
|
+
grunt.loadNpmTasks('grunt-contrib-watch');
|
|
46
|
+
grunt.loadNpmTasks('grunt-contrib-concat');
|
|
47
|
+
|
|
48
|
+
grunt.registerTask('test', ['jshint']);
|
|
49
|
+
|
|
50
|
+
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
|
|
51
|
+
|
|
52
|
+
};
|
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Quran Madina Html (no-images)
|
|
2
|
+
[](https://github.com/tarekeldeeb/quran-madina-html-no-images/actions/workflows/pylint.yml)
|
|
3
|
+
[](https://github.com/tarekeldeeb/quran-madina-html-no-images/actions/workflows/db_test.yml)
|
|
4
|
+
[](https://github.com/tarekeldeeb/quran-madina-html-no-images/actions/workflows/npm-grunt.yml)
|
|
5
|
+
|
|
6
|
+
A Madina Quran HTML Renderer without images
|
|
7
|
+
|
|
8
|
+
Theres a pre-processing python script to generate Json databases with quran text with special metadata. The preprocessing is based on text from [Tanzil](tanzil.net), and the OCR DB from [Murtaza Raja](https://github.com/murtraja/quran-android-images-helper) helper project.
|
|
9
|
+
Afterwards, the JS library uses those Json objects to render Madina-based Quran pages and lines.
|
|
10
|
+
|
|
11
|
+
The main purpose of this library is:
|
|
12
|
+
* Render Quran text that's visually similar to Madina Printed Pages
|
|
13
|
+
* Efficient Loading of Quran Visual Text (Not image-based, but pure Html)
|
|
14
|
+
* Easy to use: just a simple HTML tag! Example
|
|
15
|
+
```html
|
|
16
|
+
<quran-madina-html sura="2" aya="8-10"></quran-madina-html>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
# Dev Setup
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Fork this repo, rename it, then clone it.
|
|
23
|
+
|
|
24
|
+
$ npm install // install bower tasks
|
|
25
|
+
$ bower install // install components
|
|
26
|
+
$ grunt build // build the dependencies
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
## Project Status
|
|
30
|
+
|
|
31
|
+
In early stages, no releases yet. Check the demo for PoC.
|
|
32
|
+
|
|
33
|
+
# Demo
|
|
34
|
+
|
|
35
|
+
https://tarekeldeeb.github.io/quran-madina-html-no-images/demo/index.html
|
|
36
|
+
|
|
37
|
+
Don't forget to see the page source!
|
|
38
|
+
|
|
39
|
+
# Links
|
|
40
|
+
|
|
41
|
+
[X-Tags Docs](http://x-tags.org/docs)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bower.json
ADDED
package/build_all.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Iterates over build_db.py with multiple configurations
|
|
2
|
+
Fonts covered: Uthman, Amiri Quran Colored
|
|
3
|
+
Font Sizes: Multiple
|
|
4
|
+
|
|
5
|
+
Returns:
|
|
6
|
+
None
|
|
7
|
+
"""
|
|
8
|
+
from multiprocessing import Pool
|
|
9
|
+
from argparse import Namespace
|
|
10
|
+
from tqdm import tqdm
|
|
11
|
+
from build_db import run, DEFAULTS, REPO
|
|
12
|
+
|
|
13
|
+
amiri24 = DEFAULTS.copy()
|
|
14
|
+
amiri24['font_size']=24
|
|
15
|
+
amiri24['line_width']=400
|
|
16
|
+
|
|
17
|
+
uthman16 = DEFAULTS.copy()
|
|
18
|
+
uthman16['font_family'] = 'Uthman'
|
|
19
|
+
uthman16['font_url'] = REPO+"assets/fonts/UthmanTN_v2-0.woff2"
|
|
20
|
+
|
|
21
|
+
uthman14 = uthman16.copy()
|
|
22
|
+
uthman14['font_size'] = 14
|
|
23
|
+
uthman14['line_width'] = 240
|
|
24
|
+
|
|
25
|
+
cfgs = [ DEFAULTS, amiri24, uthman16, uthman14 ]
|
|
26
|
+
|
|
27
|
+
if __name__ == '__main__':
|
|
28
|
+
#TODO: Fix the nested progress bar
|
|
29
|
+
with Pool(4) as p:
|
|
30
|
+
r = list(tqdm(p.imap(run, list(map(lambda x: Namespace(**x) ,cfgs))), total=len(cfgs)))
|
package/build_db.py
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""Builds the JSON DB for Quran-Madina-HTML-No-Images project
|
|
2
|
+
It downloads all dependencies, process the Quran String, OCR data
|
|
3
|
+
and finally spits out the JSON DB.
|
|
4
|
+
|
|
5
|
+
Raises:
|
|
6
|
+
Exception: Unexpected Quran Content from DB
|
|
7
|
+
|
|
8
|
+
Returns:
|
|
9
|
+
None
|
|
10
|
+
"""
|
|
11
|
+
import os
|
|
12
|
+
import math
|
|
13
|
+
import json
|
|
14
|
+
import re
|
|
15
|
+
import argparse
|
|
16
|
+
import sqlite3
|
|
17
|
+
import requests
|
|
18
|
+
import tqdm
|
|
19
|
+
from bs4 import BeautifulSoup
|
|
20
|
+
from selenium import webdriver
|
|
21
|
+
from selenium.webdriver.chrome.options import Options
|
|
22
|
+
|
|
23
|
+
# Internal Constants: Do not edit!
|
|
24
|
+
TMP = "tmp_download"
|
|
25
|
+
OUT = "DBs"
|
|
26
|
+
DB = "AyahInfo_1024.db"
|
|
27
|
+
TXT = "Uthmani.txt"
|
|
28
|
+
TEST_HTML_TEMPLATE = "part_width_test.html"
|
|
29
|
+
STRETCH_ROUNDING = 3
|
|
30
|
+
REPO = 'https://raw.githubusercontent.com/tarekeldeeb/quran-madina-html-no-images/main/'
|
|
31
|
+
DEFAULTS = {'name':'Madina', 'published': 1985,
|
|
32
|
+
'title':"مصحف المدينة الإصدار القديم - مجمع الملك فهد لطباعة المصحف الشريف",
|
|
33
|
+
'font_family':'Amiri Quran Colored',
|
|
34
|
+
'font_url':REPO+'assets/fonts/AmiriQuranColored.woff2',
|
|
35
|
+
'font_size':16, 'line_width':260}
|
|
36
|
+
|
|
37
|
+
def _query(query):
|
|
38
|
+
conn = sqlite3.connect(os.path.join(TMP,DB))
|
|
39
|
+
cursor = conn.cursor()
|
|
40
|
+
cursor.execute(query)
|
|
41
|
+
result = cursor.fetchall()
|
|
42
|
+
cursor.close()
|
|
43
|
+
return result
|
|
44
|
+
|
|
45
|
+
def _get_aya_data(sura, ayah):
|
|
46
|
+
result = _query(f'select page_number, line_number from glyphs '
|
|
47
|
+
f'where sura_number={sura} and ayah_number={ayah}')
|
|
48
|
+
return list(map(list, result))
|
|
49
|
+
|
|
50
|
+
def _get_test_filename(font, size):
|
|
51
|
+
suffex = f'-{font}-{size}'
|
|
52
|
+
return "test"+suffex+".html"
|
|
53
|
+
|
|
54
|
+
def _get_surah_name(sura_id):
|
|
55
|
+
sura_name = ["الفاتحة", "البقرة", "آل عمران",
|
|
56
|
+
"النساء", "المائدة", "الأنعام", "الأعراف", "الأنفال", "التوبة",
|
|
57
|
+
"يونس", "هود", "يوسف", "الرعد", "إبراهيم", "الحجر", "النحل",
|
|
58
|
+
"الإسراء", "الكهف", "مريم", "طه", "الأنبياء", "الحج", "المؤمنون",
|
|
59
|
+
"النور", "الفرقان", "الشعراء", "النمل", "القصص", "العنكبوت",
|
|
60
|
+
"الروم", "لقمان", "السجدة", "الأحزاب", "سبأ", "فاطر", "يس",
|
|
61
|
+
"الصافات", "ص", "الزمر", "غافر", "فصلت", "الشورى", "الزخرف",
|
|
62
|
+
"الدخان", "الجاثية", "الأحقاف", "محمد", "الفتح", "الحجرات", "ق",
|
|
63
|
+
"الذاريات", "الطور", "النجم", "القمر", "الرحمن", "الواقعة",
|
|
64
|
+
"الحديد", "المجادلة", "الحشر", "الممتحنة", "الصف", "الجمعة",
|
|
65
|
+
"المنافقون", "التغابن", "الطلاق", "التحريم", "الملك", "القلم",
|
|
66
|
+
"الحاقة", "المعارج", "نوح", "الجن", "المزمل", "المدثر", "القيامة",
|
|
67
|
+
"الإنسان", "المرسلات", "النبأ", "النازعات", "عبس", "التكوير",
|
|
68
|
+
"الانفطار", "المطففين", "الانشقاق", "البروج", "الطارق", "الأعلى",
|
|
69
|
+
"الغاشية", "الفجر", "البلد", "الشمس", "الليل", "الضحى", "الشرح",
|
|
70
|
+
"التين", "العلق", "القدر", "البينة", "الزلزلة", "العاديات",
|
|
71
|
+
"القارعة", "التكاثر", "العصر", "الهمزة", "الفيل", "قريش",
|
|
72
|
+
"الماعون", "الكوثر", "الكافرون", "النصر", "المسد", "الإخلاص",
|
|
73
|
+
"الفلق", "الناس"
|
|
74
|
+
]
|
|
75
|
+
return "سورة " + sura_name[sura_id]
|
|
76
|
+
|
|
77
|
+
def _make_html(font, font_url, font_sz, line_width):
|
|
78
|
+
with open(TEST_HTML_TEMPLATE, "r", encoding="utf8") as template:
|
|
79
|
+
soup = BeautifulSoup(template.read(), 'html.parser')
|
|
80
|
+
style_elem = soup.find("style").string # type: ignore
|
|
81
|
+
style_elem = style_elem.replace("me_quran", font) # type: ignore
|
|
82
|
+
style_elem = style_elem.replace("Amiri Quran Colored", font)
|
|
83
|
+
style_elem = re.sub(r"https.*woff", font_url, style_elem)
|
|
84
|
+
style_elem = style_elem.replace("260", str(line_width))
|
|
85
|
+
style_elem = style_elem.replace("16", str(font_sz))
|
|
86
|
+
soup.find("style").string = style_elem # type: ignore
|
|
87
|
+
with open(_get_test_filename(font, font_sz), 'w', encoding="utf8") as file:
|
|
88
|
+
file.write(str(soup))
|
|
89
|
+
|
|
90
|
+
def _update_html_text(web_driver, text):
|
|
91
|
+
web_driver.execute_script(f'document.getElementById(\'test\').textContent = \'{text}\'')
|
|
92
|
+
|
|
93
|
+
def _get_width(web_driver):
|
|
94
|
+
return web_driver.execute_script("return document.getElementById('test')"
|
|
95
|
+
".getBoundingClientRect().width")
|
|
96
|
+
|
|
97
|
+
def _update_line_data(work_pointer, cfg):
|
|
98
|
+
"""Calculate the stretching factor (s), then apply to all previous line
|
|
99
|
+
parts and updates their offsets (o).
|
|
100
|
+
Finally, the returns (s,o) for the last part to be written later.
|
|
101
|
+
|
|
102
|
+
Args: work_pointer
|
|
103
|
+
suras (JSON): with complete Ayas
|
|
104
|
+
parts (list): parts of an Aya
|
|
105
|
+
sura (int): Current Surah number
|
|
106
|
+
aya (int): Current Ayah number
|
|
107
|
+
current_line (int): Line Number to update in page
|
|
108
|
+
current_line_width (float): Sum of widths of all line parts
|
|
109
|
+
"""
|
|
110
|
+
suras, parts, page, sura, aya, current_line, current_line_width = work_pointer
|
|
111
|
+
look_back = 5
|
|
112
|
+
if current_line_width<20:
|
|
113
|
+
_save_json("", suras, cfg)
|
|
114
|
+
raise ValueError(f'Problem with [short] aya={aya} of sura={sura} at line={current_line}')
|
|
115
|
+
stretch = cfg.line_width/(current_line_width) if page>2 else 1
|
|
116
|
+
aya_look_back = aya-look_back if aya>look_back else 1
|
|
117
|
+
offset = 0
|
|
118
|
+
if aya > 1:
|
|
119
|
+
search_ayas = filter(lambda a: a["p"] == page, suras[sura-1]['ayas'][aya_look_back-1:aya-1])
|
|
120
|
+
for search_aya in search_ayas:
|
|
121
|
+
for search_aya_part in search_aya['r']:
|
|
122
|
+
if search_aya_part['l'] == int(current_line):
|
|
123
|
+
tmp = search_aya_part['o']*stretch
|
|
124
|
+
search_aya_part['o'] = math.ceil(offset)
|
|
125
|
+
offset = offset + tmp
|
|
126
|
+
search_aya_part['s'] = round(stretch, STRETCH_ROUNDING)
|
|
127
|
+
if len(parts) > 0:
|
|
128
|
+
parts[-1]["o"] = math.ceil(offset*stretch)
|
|
129
|
+
parts[-1]["s"] = round(stretch, STRETCH_ROUNDING)
|
|
130
|
+
return suras, parts
|
|
131
|
+
|
|
132
|
+
def _get_json_filename(cfg):
|
|
133
|
+
json_file = f'{cfg.name}-{cfg.font_family.split()[0]}-{cfg.font_size}px.json'
|
|
134
|
+
return os.path.join(OUT, json_file)
|
|
135
|
+
|
|
136
|
+
def _save_json(json_header, suras, cfg):
|
|
137
|
+
j = json.loads(json_header)
|
|
138
|
+
j.update({"suras":suras})
|
|
139
|
+
with open(_get_json_filename(cfg), 'w', encoding="utf-8") as json_file:
|
|
140
|
+
json.dump(j, json_file, ensure_ascii = False, indent=2)
|
|
141
|
+
print(f'Saved: {_get_json_filename(cfg)}')
|
|
142
|
+
|
|
143
|
+
def run(cfg):
|
|
144
|
+
"""Runs the build_db module
|
|
145
|
+
"""
|
|
146
|
+
try:
|
|
147
|
+
os.mkdir(TMP)
|
|
148
|
+
# Start with downloading the Glyph DB
|
|
149
|
+
url = "https://raw.githubusercontent.com/murtraja/quran-android-images-helper"\
|
|
150
|
+
"/master/static/databases/" + DB.lower()
|
|
151
|
+
response = requests.get(url, timeout=500)
|
|
152
|
+
with open(os.path.join(TMP,DB), "wb") as file_db:
|
|
153
|
+
file_db.write(response.content)
|
|
154
|
+
print("Downloaded Quran DataBase")
|
|
155
|
+
#
|
|
156
|
+
# Then download the text from Tanzil.net
|
|
157
|
+
txt_url = "https://tanzil.net/pub/download/index.php?marks=true&sajdah=true"\
|
|
158
|
+
"&rub=true&tatweel=true&quranType=uthmani&outType=txt-2&agree=true"
|
|
159
|
+
req = requests.get(txt_url, timeout=500, allow_redirects=True)
|
|
160
|
+
text = req.content
|
|
161
|
+
with open(os.path.join(TMP,TXT), "wb") as file_txt:
|
|
162
|
+
file_txt.write(text)
|
|
163
|
+
print("Downloaded Quran Text file.")
|
|
164
|
+
except OSError:
|
|
165
|
+
print("Skipping download ..")
|
|
166
|
+
_make_html(cfg.font_family, cfg.font_url, cfg.font_size, cfg.line_width)
|
|
167
|
+
#
|
|
168
|
+
# Finally Load the Html Template and Driver
|
|
169
|
+
chrome_options = Options()
|
|
170
|
+
chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
|
|
171
|
+
web_driver = webdriver.Chrome(options=chrome_options)
|
|
172
|
+
dir_path = os.path.dirname(os.path.realpath(__file__))
|
|
173
|
+
web_driver.get("file://" + os.path.join(dir_path,
|
|
174
|
+
_get_test_filename(cfg.font_family, cfg.font_size)))
|
|
175
|
+
# Lets start building the json output ..
|
|
176
|
+
json_header = f'\
|
|
177
|
+
{{"title": "{cfg.title}",\
|
|
178
|
+
"published": {cfg.published},\
|
|
179
|
+
"font_family": "{cfg.font_family}",\
|
|
180
|
+
"font_url": "{cfg.font_url}",\
|
|
181
|
+
"font_size": {cfg.font_size},\
|
|
182
|
+
"line_width": {cfg.line_width}}}'
|
|
183
|
+
suras = []
|
|
184
|
+
page = aya = current_line_width = current_line = 0
|
|
185
|
+
print("Processing ..")
|
|
186
|
+
with tqdm.tqdm(total=os.path.getsize(os.path.join(TMP,TXT)), leave=False) as progress_bar:
|
|
187
|
+
with open(os.path.join(TMP,TXT), encoding="utf8") as file_txt:
|
|
188
|
+
for aya_line in file_txt:
|
|
189
|
+
progress_bar.update(len(aya_line.encode('utf-8')))
|
|
190
|
+
tokens = aya_line.strip().split('|')
|
|
191
|
+
if len(tokens) == 3:
|
|
192
|
+
prev_aya = aya
|
|
193
|
+
sura, aya, aya_text = tokens
|
|
194
|
+
if "Amiri" in cfg.font_family:
|
|
195
|
+
aya_text = aya_text + f' \u06DD{aya}'
|
|
196
|
+
else:
|
|
197
|
+
aya_text = aya_text.replace("ٱ", "ا") + f' \uFD3F{aya}\uFD3E'
|
|
198
|
+
sura = int(sura)
|
|
199
|
+
aya = int(aya)
|
|
200
|
+
#Add a Sura
|
|
201
|
+
if len(suras)<sura:
|
|
202
|
+
suras.append({"name": _get_surah_name(sura-1), "ayas":[]})
|
|
203
|
+
ayah_data = _get_aya_data(sura, aya)
|
|
204
|
+
if page < ayah_data[0][0]: #new page
|
|
205
|
+
prev_line = current_line
|
|
206
|
+
prev_line_width = current_line_width
|
|
207
|
+
prev_sura = sura-1 if aya==1 else sura
|
|
208
|
+
current_line = 1 if page>1 else 3 if page==1 else 2 #first line in page
|
|
209
|
+
current_line_width = 0
|
|
210
|
+
page = ayah_data[0][0]
|
|
211
|
+
new_page = page>0
|
|
212
|
+
else:
|
|
213
|
+
new_page = False
|
|
214
|
+
lines = {} # Key=LineNumber, Value=Number of glyphs
|
|
215
|
+
parts = [] # Break each ayah into parts/lines
|
|
216
|
+
for glyph in ayah_data:
|
|
217
|
+
if str(glyph[1]) not in lines:
|
|
218
|
+
lines.update({str(glyph[1]):1})
|
|
219
|
+
else:
|
|
220
|
+
lines[str(glyph[1])] = lines[str(glyph[1])] + 1
|
|
221
|
+
if aya==1 and sura!=1 and sura!=9:
|
|
222
|
+
skip_words = 4 #Skip Basmala from first aya. TODO: Add Basmala Manually
|
|
223
|
+
else:
|
|
224
|
+
skip_words = 0
|
|
225
|
+
if len(ayah_data) != len(aya_text.split())-skip_words:
|
|
226
|
+
print(f'Mismatch at {sura}-{aya}: Glyphs={len(ayah_data)} for:{aya_text}')
|
|
227
|
+
for line in lines:
|
|
228
|
+
if line != str(current_line): #new line
|
|
229
|
+
#Override (o,s) of previous line parts
|
|
230
|
+
if new_page:
|
|
231
|
+
work_pointer = (suras, parts, page, prev_sura,
|
|
232
|
+
prev_aya, prev_line, prev_line_width)
|
|
233
|
+
else:
|
|
234
|
+
work_pointer = (suras, parts, page, sura, aya,
|
|
235
|
+
current_line, current_line_width)
|
|
236
|
+
suras, parts = _update_line_data(work_pointer, cfg)
|
|
237
|
+
current_line_width = 0
|
|
238
|
+
current_line = int(line)
|
|
239
|
+
aya_text_part = " ".join(aya_text.split()
|
|
240
|
+
[skip_words:skip_words+lines[line]])
|
|
241
|
+
_update_html_text(web_driver, aya_text_part)
|
|
242
|
+
aya_part_width = _get_width(web_driver)
|
|
243
|
+
current_line_width = current_line_width + aya_part_width
|
|
244
|
+
parts.append({"l":int(line), "t":aya_text_part,
|
|
245
|
+
"o":aya_part_width, "s": 1.0})
|
|
246
|
+
skip_words = skip_words + lines[line]
|
|
247
|
+
suras[sura-1]["ayas"].append({"p":page, "r":parts}) # New completed ayah
|
|
248
|
+
print("Closing Chrome ..")
|
|
249
|
+
web_driver.close()
|
|
250
|
+
os.remove(_get_test_filename(cfg.font_family, cfg.font_size))
|
|
251
|
+
_save_json(json_header, suras, cfg)
|
|
252
|
+
|
|
253
|
+
if __name__ == '__main__':
|
|
254
|
+
parser = argparse.ArgumentParser(description='Build JSON DB for HTML Quran Rendering.')
|
|
255
|
+
parser.add_argument("--name", required=False, default=DEFAULTS["name"],
|
|
256
|
+
help="Mus'haf Short Name")
|
|
257
|
+
parser.add_argument("--title", required=False, default=DEFAULTS["title"],
|
|
258
|
+
help="Mus'haf Long Name")
|
|
259
|
+
parser.add_argument("--published", type=int, required=False, default=DEFAULTS["published"],
|
|
260
|
+
help="Mus'haf Publish Date")
|
|
261
|
+
parser.add_argument("--font_family", required=False, default=DEFAULTS["font_family"],
|
|
262
|
+
help="Font Family")
|
|
263
|
+
parser.add_argument("--font_url", required=False, default=DEFAULTS["font_url"],
|
|
264
|
+
help="Font URL to use")
|
|
265
|
+
parser.add_argument("--font_size", type=int, required=False, default=DEFAULTS["font_size"],
|
|
266
|
+
help="Font Size to render")
|
|
267
|
+
parser.add_argument("--line_width", type=int, required=False, default=DEFAULTS["line_width"],
|
|
268
|
+
help="Page width to render")
|
|
269
|
+
run(parser.parse_args())
|
package/db_test.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Testing the Generated JSON DB including all Quran data
|
|
2
|
+
"""
|
|
3
|
+
import unittest
|
|
4
|
+
import glob
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Test(unittest.TestCase):
|
|
9
|
+
"""Testing the Generated JSON DB including all Quran data
|
|
10
|
+
"""
|
|
11
|
+
db = []
|
|
12
|
+
for f in glob.glob('./*px.json'):
|
|
13
|
+
with open(f, 'r', encoding="utf-8") as file_handler:
|
|
14
|
+
db.append({"name":f,"data":json.load(file_handler)})
|
|
15
|
+
|
|
16
|
+
def test_0_db_fields(self):
|
|
17
|
+
"""Test all JSON header fields if exist
|
|
18
|
+
"""
|
|
19
|
+
for field in ['title','published','font_family','font_url',
|
|
20
|
+
'font_size','line_width','suras']:
|
|
21
|
+
# check if the obtained field is null or not
|
|
22
|
+
for data in self.db:
|
|
23
|
+
self.assertIsNotNone(data["data"][field]) # null will fail the test
|
|
24
|
+
|
|
25
|
+
def test_1_sura_count(self):
|
|
26
|
+
"""Test Sura Count
|
|
27
|
+
"""
|
|
28
|
+
for data in self.db:
|
|
29
|
+
self.assertEqual(len(data["data"]['suras']), 114, "Missing Suras!")
|
|
30
|
+
|
|
31
|
+
if __name__ == '__main__':
|
|
32
|
+
unittest.main()
|
package/demo/index.html
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html dir="rtl" lang="ar">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<title>quran-madina-html مشروع</title>
|
|
7
|
+
<script type="text/javascript" src="../dist/quran-madina-html-0.1.2.min.js" data-name="Madina" data-font="Uthman"></script>
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
<h2>عرض لإمكانية مشروع قران المدينة Html بدون صور</h2>
|
|
12
|
+
|
|
13
|
+
يمكن عرض نص القران قصير بشكله الجميل وسط الكلام مثل قوله تعالى:
|
|
14
|
+
<quran-madina-html sura="1" aya="3"></quran-madina-html>
|
|
15
|
+
واذا تم اختيار ايات تمتد لأكثر من سطر، فيتم عرض عدة أسطر متوافقة مع ترتيب كلمات مصحف المدينة بشكل تلقائي
|
|
16
|
+
<quran-madina-html sura="2" aya="8-10"></quran-madina-html>
|
|
17
|
+
يتميز المشروع بأنه مفتوح المصدر ويسهل تغيير الفونت، كما يعمل على مصاحف غير مصحف المدينة
|
|
18
|
+
</body>
|
|
19
|
+
|
|
20
|
+
</html>
|