--[[
القرآن
Quran
created and maintained in Arabic Wikipedia
]]
local cfg = mw.loadData('Module:Quran/Configuration')
local quran_text_data
local quran_data
local quran_norm
local aya_symbol_template = cfg.default.aya_symbol_template
local sour
local quran_shape = cfg.default.shape
local string=mw.ustring
local text=mw.text
local strspace = "[ " .. string.char(160) .. "]"
local function eastern_numbers(thenumber)
local str_number = tostring(thenumber)
local ret_str = ''
for i=1,#str_number do
ret_str = ret_str .. string.char(0x0660 + tonumber(string.sub(str_number,i,i)))
end
return ret_str
end
local function shape_numbers(thenumber)
local str_number = tostring(thenumber)
local numbers_shape = cfg.presentation.numbers_shape
if numbers_shape == "" then
return str_number
end
local ret_str = ''
local c_n
for i=1,#str_number do
c_n = tonumber(string.sub(str_number,i,i))+1
ret_str = ret_str .. string.sub(numbers_shape, c_n,c_n)
end
return ret_str
end
local gtonumber = tonumber
local function tonumber(str)
if not str then
return nil
end
local thenumber = gtonumber(str) or mw.language.getContentLanguage():parseFormattedNumber(str)
if not thenumber then
return nil
end
return math.floor(thenumber)
end
local function set_quran_shape(in_shape)
if in_shape then
for k, shapelist in pairs(cfg.shape_aliases) do
for _, shapevalue in ipairs(shapelist) do
if in_shape == shapevalue then
quran_shape = k
return
end
end
end
end
end
local function substitute( msg, args )
return args and mw.message.newRawMessage( msg, args ):plain() or msg;
end
local function error_comment(msg, args )
return substitute( cfg.presentation.error, {mw.getCurrentFrame():getParent():getTitle() , substitute( msg, args )} );
end
local function some_aya(souranum,ayanum,start_word,end_word)
if not start_word and not end_word then
return quran_data[souranum][ayanum],true
end
local fullaya = true
local ayaText = ' ' .. quran_data[souranum][ayanum] .. ' '
local f,l,wb
local fnorm=1
local norm_ayaText
if start_word then
f=string.find(ayaText,' ' .. start_word .. ' ',1,true)
if not f then
if not quran_norm then
quran_norm = mw.loadData('Module:Quran/data norm')
end
norm_ayaText=' ' .. quran_norm[souranum][ayanum] .. ' '
f=string.find(string.gsub(norm_ayaText, string.char(160),' '), ' ' .. start_word .. ' ',1,true)
fnorm=f
if not f then
return error_comment(cfg.msgs.from_word_err)
end
if quran_shape ~= 'text' and string.sub(norm_ayaText,f,f)==string.char(160) then
ff=1
tmp=1
while tmp do
tmp = string.find(string.sub(norm_ayaText,1,f),' ',ff+1,true)
if tmp then
ff=tmp
end
end
f=ff
end
_, wb = string.gsub(string.sub(norm_ayaText,1,f-1),strspace," ")
f=1
for i=1,wb do
f=string.find(ayaText," ",f+1)
end
end
end
f=f or 1
if end_word then
l=string.find(ayaText,' ' .. end_word .. ' ',f,true)
if l then
l=l + end_word:len()
else
if not quran_norm then
quran_norm = mw.loadData('Module:Quran/data norm')
end
norm_ayaText=' ' .. quran_norm[souranum][ayanum] .. ' '
l = string.find(string.gsub(norm_ayaText,string.char(160),' '),' ' .. end_word .. ' ',fnorm,true)
if not l then
return error_comment(cfg.msgs.to_word_err)
end
l=l + string.len(end_word)
_, wb =string.gsub(string.sub(norm_ayaText,1,l-1),strspace," ")
l=1
for i=1,wb do
l=string.find(ayaText, " ",l+1)
end
end
if l<#ayaText then
fullaya=false
end
end
return text.trim(string.sub(ayaText,f,l)),fullaya
end
local function argument_wrapper(arg)
local nilargs = {}
return setmetatable({},
{
__index = function ( tbl, k )
local v = rawget(tbl,k)
if v then
return v
elseif nilargs[k] then
return nil
end
local list = cfg.aliases[k];
for _,arglist in ipairs(arg) do
if type( list ) == 'table' then
for _, alias_key in ipairs( list ) do
if arglist[alias_key] then
v = arglist[alias_key]
break;
end
end
elseif list ~= nil then
v = arglist[list]
end
if v then
break;
end
end
if v == nil then
nilargs[k] = true
elseif string.len(v) == 0 then
nilargs[k] = true
v = nil
else
rawset( tbl, k, v )
end
return v
end,
});
end
local function soura_number( str_soura )
for i=1,114 do
if sour[i].name == str_soura then
return i
end
end
for i=1,114 do
for _, v in ipairs(sour[i].search) do
if v == str_soura then
return i
end
end
end
return nil
end
local function arg2soura_num(arg_soura)
local soura_num = tonumber(arg_soura)
if soura_num and (soura_num < 1 or soura_num > 114) then
return 0, error_comment(cfg.msgs.soura_num_err)
end
if not soura_num then
soura_num = soura_number(arg_soura)
if not soura_num then
return 0, error_comment(cfg.msgs.soura_name_err)
end
end
return soura_num, ""
end
local function load_data()
quran_data = mw.loadData('Module:Quran/data ' .. quran_shape)
end
local function aya_number(aya_num, frame)
if aya_symbol_template then
if cfg.presentation[aya_symbol_template] then
return substitute(cfg.presentation[aya_symbol_template], shape_numbers(aya_num))
else
return frame:expandTemplate{ title = aya_symbol_template, args = { aya_num } }
end
else
return '۝' .. eastern_numbers(aya_num)
end
end
local function get_ayat(soura, start_aya, end_aya)
local ret_text = ''
for aya_num = start_aya, end_aya do
ret_text = ret_text .. quran_data[soura][aya_num] .. aya_number(aya_num)
end
return string.sub(ret_text,1,#ret_text -1)
end
local function aya(frame)
local A = argument_wrapper({frame.args, frame:getParent().args,mw.loadData("Module:Art pref/data")["قرآن"] or {}})
local soura = tonumber(A[1] or A.soura or A.s)
local aya = tonumber(A.from_aya or A.a)
local ret = ''
if soura> 114 or soura<1 then
return error_comment(cfg.msgs.soura_num_err)
end
if A.shape then
set_quran_shape(A.shape)
end
local soura_data = mw.loadData('Module:Quran/data general').sour[soura]
if aya <1 or aya > soura_data.ayacount then
return error_comment(cfg.msgs.from_aya_err,{soura_data.name,soura_data.ayacount})
end
load_data()
local ret = quran_data[soura][aya]
if quran_shape == "KFGQPC" then
ret= string.gsub(ret,'آ', 'آ')
end
return ret
end
local function search(A, frame)
local soura= A[1] or A.soura
local start_soura
local ret = ''
sour = mw.loadData('Module:Quran/data general').sour
if soura then
start_soura, errmsg = arg2soura_num(soura)
if start_soura == 0 then
return errmsg
end
end
quran_norm = mw.loadData('Module:Quran/data norm')
start_soura = start_soura or 1
for soura_num=start_soura,114 do
for aya_num=1,sour[soura_num].ayacount do
if quran_norm[soura_num][aya_num]:gsub("\160"," "):find(A.search) then
if not quran_data then load_data() end
ret = ret .. "*" .. substitute(cfg.presentation.quran, { quran_shape, quran_data[soura_num][aya_num] .. ' ' .. aya_number(aya_num,frame)}) .. substitute(cfg.presentation.cite_quran, { sour[soura_num].name, ':' .. aya_num}) .. "\n"
if A.viewtemplate and A.viewtemplate=="1" or A.viewtemplate=="نعم" then
ret = ret .. substitute("<pre>{{قرآن|$1|$2}}</pre>",{soura_num,aya_num}) .. "\n"
end
end
end
end
if #ret==0 then
return error_comment("لا نتائج")
else
return ret
end
end
local function ayat(frame)
local A = argument_wrapper({frame:getParent().args, frame.args,mw.loadData("Module:Art pref/data")["قرآن"] or {}})
local nocite = A["no-cite"] and A["no-cite"] ~= '0' and A["no-cite"] ~= 'لا'
if A.shape and string.len(A.shape)>0 then
set_quran_shape(A.shape)
if quran_shape=='Text' then
strspace = "[ " .. string.char(160) .. "]"
else
strspace = " "
end
end
if A.aya_template and (cfg.presentation[A.aya_template] or mw.title.new("template:" .. A.aya_template).exists) then
aya_symbol_template = A.aya_template
end
if A.search and string.len(A.search)>0 then
return search(A,frame)
end
sour = mw.loadData('Module:Quran/data general').sour
local ret_text = ""
if A.from_aya and string.len(A.from_aya)> 0 then
local soura_num, soura, from_aya, to_aya, errmsg
soura_num, errmsg = arg2soura_num(A[1] or A.soura)
if soura_num == 0 then
return errmsg
end
soura = sour[soura_num]
if string.find(A.from_aya,'-',1,true) then
local from_aya_splits = mw.text.split(A.from_aya, '-', true )
from_aya = tonumber(from_aya_splits[1])
to_aya = tonumber(from_aya_splits[2])
else
from_aya = tonumber(A.from_aya)
end
if not from_aya or from_aya>soura.ayacount or from_aya<1 then
return error_comment(cfg.msgs.from_aya_err,{soura.name,soura.ayacount})
end
if not to_aya or to_aya>soura.ayacount then
local arg_aya_add = A.addition_ayat
if arg_aya_add then
to_aya = from_aya + (tonumber(arg_aya_add) or 0)
elseif A.to_aya then
to_aya = tonumber(A.to_aya)
else
to_aya = from_aya
end
end
if to_aya>soura.ayacount or to_aya<1 then
return error_comment(cfg.msgs.to_aya_err,{soura.name,soura.ayacount})
end
load_data()
for aya_num = from_aya, to_aya do
local fullaya=true
if (aya_num==from_aya or aya_num == to_aya) and (A.from_word or A.to_word) then
local temp_text
temp_text, fullaya = some_aya(soura_num,aya_num,
(aya_num==from_aya and A.from_word or nil),
(aya_num == to_aya and A.to_word or nil))
if temp_text:find("error") then
return temp_text
end
ret_text = ret_text .. temp_text
else
ret_text = ret_text .. quran_data[soura_num][aya_num]
end
if fullaya then
ret_text = ret_text .. ' ' .. aya_number(aya_num, frame) .. ' '
end
end
if quran_shape == "KFGQPC" then
ret_text = string.gsub(ret_text,'آ', 'آ')
end
return substitute(cfg.presentation.quran, { quran_shape, text.trim(ret_text) }) .. ((not nocite) and (substitute(cfg.presentation.cite_quran, { soura.name, ':' .. from_aya .. ((to_aya>from_aya) and ("–" .. to_aya) or '')})) or "")
else
ret_text = substitute(cfg.presentation.quran, { quran_shape, A[1] or A.user_text })
if A.s and string.len(A.s)>0 then
local soura_num, errmsg = arg2soura_num(A.s)
if soura_num == 0 then
return errmsg
end
local soura=sour[soura_num]
ret_text = ret_text .. substitute(cfg.presentation.cite_quran, { soura.name, (A.a and (":" .. A.a) or "")})
end
return ret_text
end
end
local function number_of_soura( frame )
local idx = tonumber(frame.args[1])
if idx and idx>=1 and idx <=114 then
return idx
end
sour = mw.loadData('Module:Quran/data general').sour
return soura_number(frame.args[1])
end
local function soura_name( frame )
local idx = tonumber(frame.args[1])
if not idx or idx<1 or idx > 114 then
return nil
end
sour = mw.loadData('Module:Quran/data general').sour
return sour[idx].name
end
local function aya_count( frame )
local idx = tonumber(frame.args[1])
if not idx or idx<1 or idx > 114 then
return nil
end
sour = mw.loadData('Module:Quran/data general').sour
return sour[idx].ayacount
end
return {
aya = aya,
ayat=ayat,
number_of_soura = number_of_soura,
soura_name = soura_name,
aya_count = aya_count
}