Modul:balans
Dokumentation för denna modul finns på /dok (redigera), /test
Används enbart på sidan Wiktionary:Balans efter språk och ordklass.
-- obligatory named parameter "list="
-- optional named parameter "limit="
-- optional named parameter "aggressive=true"
-- optional named parameter "debug=true"
-- MUST NOT be substituted per "subst:" if "aggressive=true" used
local exporttbl = {}
local import_lang = require ("Modul:lang")
clang = "spr" .. string.char(195,165) .. "k"
cucflang = "Spr" .. string.char(195,165) .. "k"
cbadlang = "ok" .. string.char(195,164) .. "nt " .. clang
crekn = "r" .. string.char(195,164) .. "kn."
crekord = "R" .. string.char(195,164) .. "kneord"
cfor = "f" .. string.char(195,182) .. "r"
const_table_title = '<tr><th>Kod</th><th>' .. cucflang .. 'namn</th><th>Antal<br>huvud-<br>uppslag</th>'
const_table_title = const_table_title .. '<th>%<br>subst.</th><th>%<br>verb</th><th>%<br>adj.</th><th>%<br>adverb</th>'
const_table_title = const_table_title .. '<th>Former<br>per<br>subst.</th><th>Former<br>per<br>verb</th>'
const_table_title = const_table_title .. '<th>Former<br>per<br>adj.</th><th>Former<br>per<br>adv.</th>'
const_table_title = const_table_title .. '<th>Antal<br>konj.</th><th>Antal<br>subj.</th><th>Antal<br>prep.</th>'
const_table_title = const_table_title .. '<th>Antal<br>pron.</th><th>Antal<br>' .. crekn .. '</th><th>Antal<br>mallar</th></tr>'
local big_word_classes = {"Substantiv", "Verb", "Adjektiv", "Adverb"}
local tiny_word_classes = {"Konjunktioner", "Subjunktioner", "Prepositioner", "Pronomen", crekord}
local function ucFirst(str)
return mw.ustring.gsub(str, "^%l", mw.ustring.upper)
end
local function ifExistEnhanced (arxinp3,strpgname,aggressive_mode)
local boomemangada = false
local metaa = 0
if (aggressive_mode) then -- does NOT work with substitution
boomemangada = ( '[[:' .. strpgname .. ']]' ~= arxinp3:preprocess ('{{msgnw::' .. strpgname .. '}}') )
else
metaa = mw.title.new (strpgname) -- 1 param
boomemangada = metaa.exists -- expensive
end--if
return boomemangada
end--function ifExistEnhanced
local function pagesInCategoryEnhanced (strcatname)
local metab = 0
local numpages = 0
local numsubcats = 0
metab = mw.site.stats.pagesInCategory ( strcatname, "*" ) -- expensive
numpages = metab.pages
numsubcats = metab.subcats
if (numpages<0) then
numpages = 0 -- YES MediaWiki is stupid
end--if
if (numsubcats<0) then
numsubcats = 0 -- YES MediaWiki is stupid
end--if
return numpages, numsubcats
end--function pagesInCategoryEnhanced
local function floatToString (incoming_number)
local result_conv = ''
local decimals = 0
local num_temp = 0
local remainder = 0
local conversion_index = 0
local boo_trim_right = true
if (incoming_number<0) or (incoming_number>3000000000) then -- 3 G max
result_conv = '??'
else
if (incoming_number<30) then
decimals = 1
end--if
if (incoming_number<3) then
decimals = 2
end--if
if (decimals==1) then
incoming_number = incoming_number * 10
end--if
if (decimals==2) then
incoming_number = incoming_number * 100
end--if
incoming_number = math.floor (incoming_number+0.5) -- now integer
while true do
num_temp = math.floor (incoming_number / 10)
remainder = incoming_number - (10 * num_temp)
incoming_number = num_temp
if ((conversion_index==decimals) and (not boo_trim_right)) then
result_conv = "." .. result_conv
end--if
num_temp = conversion_index - decimals -- can be negative
if ((num_temp==3) or (num_temp==6) or (num_temp==9)) then
result_conv = "'" .. result_conv
end--if
if ((remainder~=0) or (conversion_index==decimals)) then
boo_trim_right = false -- never back to true
end--if
if (not boo_trim_right) then
result_conv = string.char(remainder+48) .. result_conv
end--if
conversion_index = conversion_index + 1 -- number of digits written including trimmed ones
if ((incoming_number==0) and (conversion_index>decimals)) then
break
end--if
end--while
end--if
return result_conv
end--function floatToString
local function secureDivide (part, whole, boo_percent)
local my_percent = ''
local scale = 1
local fraction = 0
if (boo_percent==true) then
scale = 100
end--if
if (whole==0) then -- avoid criminal division by ZERO (but part>whole is legal here)
my_percent = '??'
else
if (part==0) then
my_percent = '0'
else
fraction = (part*scale) / whole
if (fraction<0.03) then
my_percent = '<0.03'
else
my_percent = floatToString(fraction)
end--if
end--if (part==0) then
end--if
return my_percent
end--function secureDivide
function exporttbl.go (arxframent) -- main
local arxsomons = 0
local temp = 0
local lng_codes = {} -- from "list="
local tbl_count_of_cat = {} -- backup counts
local par_list_codes = ""
local strlngcode = ""
local strlngnamelc = ""
local strlngnameup = ""
local picked_word_class = ""
local strcatname = ""
local stritem = ""
local strret = ""
local limit_que = 0 -- shared as upvalue
local consumed_que_total = 0 -- shared as upvalue
local consumed_real = 0 -- shared as upvalue
local error_code = 0 -- 0 OK | 1 ano | 2 li | 3 subst | 5 bad co | 6 cost
local panja = 0
local index = 0
local posi = 0
local chx = 0
local numcodelen = 0
local num_count_of_all = 0
local num_count_of_cat = 0
local boo_debug = false -- parameter
local boo_existence_of_cat = false
local boo_is_substed = false
local boo_aggressive_ifexist = false -- shared as upvalue -- parameter
local boo_cost_problem = false -- shared as upvalue
arxsomons = arxframent.args -- "args" from our own "frame"
if (arxsomons['caller']=="true") then
arxsomons = arxframent:getParent().args -- "args" from caller's "frame"
end--if
local function ifExistHigh (page_name_ex) -- uses upvalues
local boo_successcost = false
local boo_existence = true -- bad guess
if (consumed_que_total<limit_que) then -- upvalues
boo_successcost,boo_existence = pcall (ifExistEnhanced, arxframent, page_name_ex, boo_aggressive_ifexist)
if (not boo_successcost) then
boo_cost_problem = true -- upvalue
boo_existence = true -- bad guess -- YES do show stupid red link
end--if
end--if
consumed_que_total = consumed_que_total + 1 -- inc in any case
if (not boo_aggressive_ifexist) then
consumed_real = consumed_real + 1
end--if
return boo_existence
end--function
local function PagesInCategoryHigh (page_name_cat) -- uses upvalues
local boo_success_pik = false
local result_pages = 0 -- bad guess
local result_subcats = 0 -- bad guess
if (consumed_que_total<limit_que) then -- upvalues
boo_success_pik, result_pages, result_subcats = pcall (pagesInCategoryEnhanced, page_name_cat)
if (not boo_success_pik) then
boo_cost_problem = true -- upvalue
result_pages = 0 -- bad guess
result_subcats = 0 -- bad guess
end--if
end--if
consumed_que_total = consumed_que_total + 1 -- inc in any case
consumed_real = consumed_real + 1 -- inc in any case
return result_pages, result_subcats
end--function
while (true) do -- fake loop
error_code = 1 -- prepare
if (arxsomons[1]~=nil) then
break -- no anonymous parameters tolerated
end--if
error_code = 2 -- prepare -- broken "list=" parameter
temp = arxsomons["list"]
if (type(temp)=="string") then
panja = string.len(temp)
if ((panja>=2) and (panja<=100000)) then
par_list_codes = temp
end--if
end--if
if (par_list_codes=='') then
break -- broken "list=" parameter
end--if
limit_que = 999999 -- default: no limit
temp = arxsomons["limit"]
if (type(temp)=="string") then
panja = string.len(temp)
if ((panja>0) and (panja<7)) then -- 0...999'999
limit_que = tonumber (temp) or 0
end--if
end--if
boo_debug = (arxsomons["debug"]=="true")
boo_aggressive_ifexist = (arxsomons["aggressive"]=="true")
boo_is_substed = mw.isSubsting()
if boo_aggressive_ifexist and boo_is_substed then
error_code = 3
break -- this does not work together
end--if
error_code = 0 -- prepare -- OK
index = 0 -- also needed far below for error complaint
posi = 0
panja = string.len(par_list_codes)
while (true) do -- genuine inner loop over codes
strlngcode = ""
numcodelen = 0
if (posi>=panja) then
break -- inner loop for now
end--if
while (true) do -- genuine deep loop over octets
if (posi>=panja) then
break -- deep loop for now
end--if
chx = string.byte(par_list_codes,(posi+1),(posi+1))
posi = posi + 1
if (chx==44) then -- comma ","
break -- deep loop for now
end--if
strlngcode = strlngcode .. string.char(chx)
numcodelen = numcodelen + 1
end--while -- deep loop
if ((numcodelen<2) or (numcodelen>10)) then
error_code = 2 -- broken "list=" parameter detected
break -- inner loop
end--if
index = index + 1
lng_codes[index] = strlngcode
end--while -- genuine inner loop over codes
if (error_code~=0) then
break -- error inside above loop
end--if
if (#lng_codes==0) then
error_code = 2 -- broken "list=" parameter detected -- empty
break
end--if
table.sort(lng_codes)
error_code = 0 -- prepare
index = 0 -- also needed far below for error complaint
while (true) do -- genuine inner loop over codes
strlngcode = lng_codes[index+1]
if (strlngcode==nil) then
break -- done
end--if
boo_is_last = not lng_codes[index+2]
strlngnamelc = import_lang.getLanguage(strlngcode)
if (strlngnamelc==cbadlang) then
error_code = 5 -- bad lang code detected -- inner loop for now
break
end--if
strlngnameup = ucFirst(strlngnamelc)
stritem = '<tr><td>' .. strlngcode .. '</td>' -- all base form lemmas
stritem = stritem .. '<td>[[:Kategori:' .. strlngnameup .. '|' .. strlngnamelc .. ']]</td>'
strcatname = strlngnameup .. "/Alla uppslag"
num_count_of_all = PagesInCategoryHigh (strcatname)
stritem = stritem .. '<td>[[:Kategori:' .. strcatname .. '|' .. floatToString(num_count_of_all) .. ']]</td>'
posi = 1 -- base word class as fraction of all base form lemmas
while true do -- genuine deep loop over big word classes
picked_word_class = big_word_classes[posi]
if (picked_word_class==nil) then
break
end--if
strcatname = strlngnameup .. "/" .. picked_word_class
boo_existence_of_cat = ifExistHigh ('Kategori:'..strcatname)
num_count_of_cat = PagesInCategoryHigh (strcatname)
if ((not boo_existence_of_cat) and (num_count_of_cat==0)) then
stritem = stritem .. '<td>-</td>'
else
stritem = stritem .. '<td>[[:Kategori:' .. strcatname .. '|' .. secureDivide(num_count_of_cat,num_count_of_all,true) .. ']]</td>'
tbl_count_of_cat[posi] = num_count_of_cat
end--if
posi = posi + 1
end--while
posi = 1 -- non-base forms divided by base forms (can be >1 or <1)
while true do -- genuine deep loop over big word classes
picked_word_class = big_word_classes[posi]
if (picked_word_class==nil) then
break
end--if
strcatname = strlngnameup .. "/" .. picked_word_class .. "former"
boo_existence_of_cat = ifExistHigh ('Kategori:'..strcatname)
num_count_of_cat = PagesInCategoryHigh (strcatname)
if ((not boo_existence_of_cat) and (num_count_of_cat==0)) then
stritem = stritem .. '<td>-</td>'
else
stritem = stritem .. '<td>[[:Kategori:' .. strcatname .. '|' .. secureDivide(num_count_of_cat,tbl_count_of_cat[posi],false) .. ']]</td>'
end--if
posi = posi + 1
end--while
posi = 1 -- raw counts for tiny word classes
while true do -- genuine deep loop over tiny word classes
picked_word_class = tiny_word_classes[posi]
if (picked_word_class==nil) then
break
end--if
strcatname = strlngnameup .. "/" .. picked_word_class
boo_existence_of_cat = ifExistHigh ('Kategori:'..strcatname)
num_count_of_cat = PagesInCategoryHigh (strcatname)
if ((not boo_existence_of_cat) and (num_count_of_cat==0)) then
stritem = stritem .. '<td>-</td>'
else
stritem = stritem .. '<td>[[:Kategori:' .. strcatname .. '|' .. floatToString(num_count_of_cat) .. ']]</td>'
end--if
posi = posi + 1
end--while
strcatname = "Wiktionary:Mallar " .. cfor .. " " .. strlngnamelc -- language-specific templates
boo_existence_of_cat = ifExistHigh ('Kategori:'..strcatname)
num_count_of_cat = PagesInCategoryHigh (strcatname)
if ((not boo_existence_of_cat) and (num_count_of_cat==0)) then
stritem = stritem .. '<td>-</td>'
else
stritem = stritem .. '<td>[[:Kategori:' .. strcatname .. '|' .. floatToString(num_count_of_cat) .. ']]</td></tr>'
end--if
strret = strret .. stritem
if (boo_cost_problem) then -- assigned in function as upvalue
error_code = 6
break
end--if
index = index + 1
end--while -- genuine inner loop over codes
break -- finally to join mark
end--while -- fake loop -- join mark
if (error_code==0) then
strret = '<table class="wikitable sortable" style="text-align:center>' .. const_table_title .. strret .. const_table_title .. '</table>'
end--if
if (error_code==1) then
strret = 'No anonymous parameters appreciated.'
end--if
if (error_code==2) then
strret = 'CSV syntax error in parameter "list=" at index ' .. tostring(index) .. '.'
end--if
if (error_code==3) then
strret = 'Substitution and "aggressive=true" exclude each other.'
end--if
if (error_code==5) then
strret = 'Bad language code "' .. strlngcode .. '".'
end--if
if (error_code==6) then
strret = 'Cost limit exceeded with language code "' .. strlngcode .. '" at index ' .. tostring(index) .. '.'
end--if
if (error_code~=0) then
strret = "ERROR: " .. strret
end--if
if boo_debug then
strret = strret .. '<br>Error code : ' .. tostring (error_code)
strret = strret .. '<br>Number of languages in list : ' .. tostring (#lng_codes)
strret = strret .. '<br>Index on exit : ' .. tostring (index)
strret = strret .. '<br>Limit : ' .. tostring (limit_que)
strret = strret .. '<br>Aggressive ifexist mode : ' .. tostring (boo_aggressive_ifexist)
strret = strret .. '<br>Subst : ' .. tostring (boo_is_substed)
strret = strret .. '<br>Consumed possibly expensive : ' .. tostring (consumed_que_total)
strret = strret .. '<br>Consumed really expensive : ' .. tostring (consumed_real) .. '<br>'
end--if
return strret
end
return exporttbl