Moduuli:ValidateInfobox
Siirry navigaatioon
Siirry hakuun
[ muokkaa ]
Tarkista luku -mallineen tarkistuslogiikka. Artikkelit jotka epäonnistuvat tarkistuksessa luokitellaan luokkaan Virheellinen arvo tietolaatikossa. |
require('Moduuli:Magic-escape')
local validator = {}
function validator.IUCN(frame)
local new_args = validator._getParameters( frame.args, {'status', 'tunnus'} );
local iucn= mw.ustring.lower(new_args['status'] or '');
local tunnus= new_args['tunnus'] ;
local wd_redirect = {
Q96377276 = "Q11394"
}
if (iucn == "") then
return "";
end
if (iucn == "elinvoimainen") then iucn_wd="Q211005";
elseif (iucn=="silmälläpidettävä") then iucn_wd="Q719675";
elseif (iucn=="vaarantunut") then iucn_wd="Q278113";
elseif (iucn=="erittäin uhanalainen") then iucn_wd="Q11394";
elseif (iucn=="äärimmäisen uhanalainen") then iucn_wd="Q219127";
elseif (iucn=="luonnosta hävinnyt" ) then iucn_wd="Q239509";
elseif (iucn=="puutteellisesti tunnettu" ) then iucn_wd="Q3245245";
elseif (iucn=="hävinnyt" ) then iucn_wd="Q237350";
elseif (iucn==mw.ustring.lower(frame:expandTemplate{title="elinvoimainen"}) ) then iucn_wd="Q211005";
elseif (iucn==mw.ustring.lower(frame:expandTemplate{title="silmälläpidettävä"}) ) then iucn_wd="Q719675";
elseif (iucn==mw.ustring.lower(frame:expandTemplate{title="vaarantunut"}) ) then iucn_wd="Q278113";
elseif (iucn==mw.ustring.lower(frame:expandTemplate{title="erittäin uhanalainen"}) ) then iucn_wd="Q11394";
elseif (iucn==mw.ustring.lower(frame:expandTemplate{title="äärimmäisen uhanalainen"}) ) then iucn_wd="Q219127";
elseif (iucn==mw.ustring.lower(frame:expandTemplate{title="luonnosta hävinnyt"}) ) then iucn_wd="Q239509";
elseif (iucn==mw.ustring.lower(frame:expandTemplate{title="puutteellisesti tunnettu"}) ) then iucn_wd="Q3245245";
elseif (iucn==mw.ustring.lower(frame:expandTemplate{title="hävinnyt"}) ) then iucn_wd="Q237350";
else iucn_wd = "FAIL";
end
entity = mw.wikibase.getEntityObject();
if not entity then
return "";
end
if not entity.claims then
return "";
end
ok=0;
wikidata_iucn_claims= entity.claims["P141"];
if (wikidata_iucn_claims~=nil) then
for i, statement in pairs( wikidata_iucn_claims ) do
if statement.rank == 'preferred' or statement.rank == 'normal' then
wikidata_iucn="Q" .. statement.mainsnak.datavalue.value['numeric-id'];
if wd_redirect[wikidata_iucn] ~= nil then
wikidata_iucn = wd_redirect[wikidata_iucn];
end
if (wikidata_iucn == iucn_wd) then
return "<span class='wd_tests'>[https://tools.wmflabs.org/fiwiki-tools/testit/".. tunnus .."/OK/IUCN IUCN-testi OK]</span>";
end
end
end
ret="[[Luokka:Taksoboksin status-parametri ei vastaa Wikidatassa olevaa IUCN-arvoa]]";
ret=ret .. "<span class='wd_tests'>[https://tools.wmflabs.org/fiwiki-tools/testit/" .. tunnus .. "/FAIL/IUCN Virheellinen IUCN-arvo][[Luokka:IUCN-uhanalaisuusluokitus eroaa Wikidatasta]]</span>";
return ret;
else
return ""; -- P141 ei ole määritelty Wikidatassa
end
end
function validator.split(str, pat)
local t = {} -- NOTE: use {n = 0} in Lua-5.0
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
function validator.trim(s)
return s:match "^%s*(.-)%s*$"
end
function validator.glue_numbers(s)
s=mw.text.trim(s)
s=mw.ustring.gsub(s, " ", "");
pattern="^(-?[0123456789/–+,.]+)";
local iterator = mw.text.gsplit(s, "%s");
local out=""
for w in iterator do
result = mw.ustring.match( w, pattern, 1 );
if result ~= nil then
out=out .. w
else
out=out .. " " .. w
end
end
return mw.text.trim(out)
end
function validator.wikidata_name(frame)
local new_args = validator._getParameters( frame.args, {'nimi', 'tunnus', 'huomioi kirjainkoko'} );
local input_name_str = new_args['nimi'] or '';
local tunnus = new_args['tunnus'] or '';
local case_sensitive = new_args['huomioi kirjainkoko'] or '';
local langs = {'fi', 'en', 'de', 'sv', 'no', 'ru'}
local aliases = {}
local aliases_debug="";
local name_debug="";
local split_debug="";
local match_postfix="$";
if input_name_str =="" then
return "";
end
if tunnus=="" then
return "";
end
entity = mw.wikibase.getEntityObject()
if not entity then return nil end
id = entity.id
for l, lang in pairs(langs) do
local tmp_name=entity:getLabel( lang );
if tmp_name ~= nil then
if case_sensitive =='' then
table.insert( aliases, string.lower(tmp_name) );
else
table.insert( aliases, tmp_name );
end
end
if entity.aliases and entity.aliases[lang] ~= nil then
for i, alias in pairs( entity.aliases[lang] ) do
if case_sensitive =='' then
table.insert( aliases, string.lower(alias.value) );
else
table.insert( aliases, alias.value );
end
end
end
end
input_name_str= string.gsub (input_name_str, "(<%s*small[^>]*>)", "");
input_name_str= string.gsub (input_name_str, "(<%s*span[^>]*>)", "");
local names=validator.split(input_name_str, "\<br\>");
for k1, name in pairs( names ) do
if mw.text.trim(name) ~= "" then
-- Poistetaan viitteet
name=mw.text.killMarkers( name );
--Poistetaan kursivoinnit
name=string.gsub( name, "'", "");
if case_sensitive =='' then
name=string.lower(name);
end
name=mw.text.trim(name);
names[k1]=name;
if k1>1 then
match_postfix="";
end
else
table.remove(names, k1);
end
end
local ok=1;
for k, name in pairs(names) do
part_ok=0;
for _,wikidata_name in pairs(aliases) do
if name==wikidata_name then
f=true
else
-- Escapee kaikki erikoismerkit
wikidata_name=magic_escape(wikidata_name);
f=(string.find(name,"^" .. wikidata_name .. match_postfix ) or name==wikidata_name);
end
-- Tarkista onko ylläolevan ehdon vuoksi f aina true/false eikä ikinä nil.
if (f ~= nil) and f then
part_ok=1;
break;
end
end
-- Jos tulee yksikin osa joka ei läpäise testiä, niin luovutetaan.
if part_ok==0 then
ok=0;
break;
end
end
if ok == 1 then
return "<span class='wd_tests'>[https://tools.wmflabs.org/fiwiki-tools/testit/".. tunnus .."/OK/NIMI Nimi-testi OK]</span>";
else
ret="[[Luokka:Tietolaatikon nimi-parametri ei vastaa Wikidatassa olevaa nimeä]]";
ret=ret .. "<span class='wd_tests'>[https://tools.wmflabs.org/fiwiki-tools/testit/" .. tunnus .. "/FAIL/NIMI Virheellinen NIMI-arvo]</span>";
return ret;
end
end
-- Funktio yrittää tarkistaa "342 – 43243" -tyyppiset arvovälit myös.
function validator._parse_number_str(target_str, min_value, max_value)
local number_match_1 = "^(-?%d+[.,]?%d*)[– ]+-?(%d+[.,]?%d*)$";
local number_match_2 = "^(-?%d+[.,]?%d*)%s*[+]%s*(-?%d+[.,]?%d*)$";
local number_match_3 = "^(-?%d+[.,]?%d*)%s*[/]%s*(-?%d+[.,]?%d*)$";
local number_match_4 = "^(-?%d+[.,]?%d*)$";
local numbers={};
local delim = " – ";
-- arvo: 1 – 10
local numbers ={ string.match( target_str, number_match_1)};
-- arvo: 1 + 10
if numbers[1] == nil then
numbers = {string.match( target_str, number_match_2)};
delim=" + ";
end
-- arvo: 1 / 10
if numbers[1] == nil then
numbers = {string.match( target_str, number_match_3)};
delim=" / ";
end
-- arvo: 1
if numbers[1] == nil then
numbers = {string.match( target_str, number_match_4)};
end
if numbers[1] == nil then
return "unknown_value_error";
end
for k,v in pairs(numbers) do
local number=tonumber(tostring(mw.ustring.gsub(v, ",", ".")));
if max_value ~= nil and max_value<number then
return "max_value_error";
elseif min_value ~= nil and min_value>number then
return "min_value_error";
end
local lang= mw.getContentLanguage();
-- Don't formatNum too small numbers because exponential notation
if number == 0 or number > 0.0001 or number < -0.0001 then
numbers[k]=lang:formatNum(number);
else
numbers[k]=string.format("%f", number);
end
end
local ret=numbers[1];
if numbers[2] ~= nil then
ret = ret .. delim .. numbers[2];
end
return ret;
end
-- Tarkistaa onko kuva-parametrin sisältö wikikoodia, jos ei ole
-- niin tarkistetaan sisältääkö parametri kuvan nimen
-- jos sisältää, niin tulostetaan nimen ympärille kuvan vaatima wikikoodi.
function validator.wikify_image_name(frame)
local new_args = validator._getParameters( frame.args, {'image', 'image_width', 'image_description', 'wikidata_image', 'wikidata_image_description'} );
local image=new_args['image'] or '';
local image_width=new_args['image_width'] or '';
local image_description=new_args['image_description'] or '';
local wikidata_image=new_args['wikidata_image'] or 'P18';
local wikidata_image_description=new_args['wikidata_image_description'] or 'P2096';
local wikicode_tests={"%[%[", "%]%]", "%{%{", "%}%}", "%|"};
local supported_file_formats={"jpg", "jpeg", "png", "gif", "svg", "tif", "tiff", "xcf"};
if image=="" then
return ;
end
if image=="-" then
return ;
end
if image_width == '' then
image_width="250px";
end
-- Tarkistetaan onko syöte wikikoodia
local s=string.lower(image);
for i, test_pattern in ipairs(wikicode_tests) do
local result=mw.ustring.match( s, test_pattern, 1 );
if result ~= nil then
return image;
end
end
-- Tarkistetaan onko syöte kuvan nimi
for i, test_pattern in ipairs(supported_file_formats) do
local result=mw.ustring.match( s, test_pattern .."$", 1 );
if result ~= nil then
if image_description ~= "" then
image="[[file:" .. image .."|" .. image_width .."|" .. image_description .."]]";
else
image="[[file:" .. image .."|" .. image_width .."]]";
end
break;
end
end
return image;
end
function validator.plain_number(frame)
local new_args = validator._getParameters( frame.args, {'s', 'unit', 'template'} );
local s = new_args['s'] or '';
local start = 1;
local type = 'integer';
local template_name = new_args['template'] or 'unknown';
local unit = new_args['unit'] or '';
local pattern="^([+-]?%d+[.,]?%d*)$";
local number_type_str = "desimaaliluku";
local template_link_message;
local lang= mw.getContentLanguage();
result = mw.ustring.match( s, pattern, start );
if result ~= nil then
local result_num=tonumber(tostring(mw.ustring.gsub(result, ",", ".")));
local unit_message="";
if unit ~= "" then
unit_message= ' ' .. mw.text.trim(unit);
end
-- Dont formatNum small numbers because exponential notation
if result_num > 0.0001 then
result_num_message=lang:formatNum(result_num);
else
result_num_message=string.format("%f", result_num);
end
return result_num_message .. unit_message ;
else
local template_link_message='[[malline:' ..template_name ..'|' ..template_name ..']]';
local format_error_message = 'Mallineen ' .. template_link_message .. ' parametrin <code><nowiki>{{{1}}}</nowiki></code> arvon muoto <code><nowiki>' .. s .. '</nowiki></code> on virheellinen. Arvon pitäisi olla desimaaliluku. ';
local example_message = 'Esimerkki käytöstä: <code><nowiki>{{' ..template_name ..'|10000|km}}</nowiki></code> tulostaa tekstin "' .. lang:formatNum(10000) .. ' km".';
return s .. validator._error( format_error_message .. ' ' .. example_message) ;
end
end
-- funktio tarkistaa onko syötteen alkuosa numero ja onko se haluttua tyyppiä,
-- mikäli ei ole, niin se tulostaa virheen jossa se kertoo mistä virhe tulee.
-- Mikäli syöte on "" (tyhjä) palautetaan "";
-- Mikäli syöte on "-" palautetaan "-" (Wikidata-moduulin taikasana sille ettei haluta mitään tulostettavan)
function validator.number_with_unit( frame )
local new_args = validator._getParameters( frame.args, {'s', 'type', 'allowed units', 'template', 'parameter', 'default unit', 'error message', 'min', 'max', 'word_delim'} );
local s = new_args['s'] or '';
local start = 1;
local type = new_args['type'] or 'integer';
local allowed_units = new_args['allowed units'] or '$';
local default_unit = new_args['default unit'];
local template_name=new_args['template'] or 'tuntematon';
local parameter_name=new_args['parameter'] or 'tuntematon';
local error_message=new_args['error message'] or '';
local max_value;
local min_value;
local word_delim=new_args['word_delim'] or ' ';
if new_args['max'] ~=nil then
max_value=tonumber(new_args['max']);
end
if new_args['min'] ~=nil then
min_value=tonumber(new_args['min']);
end
local number_type_str;
-- Siivotaan syötettä sen verran, että yhdistetään numerot poistamalla välilyönnit
s=validator.glue_numbers(s)
-- Poistetaan luvun alussa olevat kuvailevat sanat
local prefixlist = { 'noin', 'yli', 'alle', 'maks.', 'keskim.', 'min.', 'enimmillään' }
local prefix = ""
for i, testprefix in ipairs(prefixlist) do
prefix_pattern = "^" .. testprefix;
result = mw.ustring.gsub( s, prefix_pattern, "" );
if (s ~= result ) then
s=result
prefix=testprefix
break
end
end
if s == '-' then
return '-';
elseif s == '' then
return '';
end
if type == 'integer' then
pattern="^(-?[0123456789/–+ ]+)";
number_type_str = "kokonaisluku";
elseif type == 'float' then
pattern="^(-?[0123456789/–+ ,.]+)";
number_type_str = "desimaaliluku";
else
return validator._error( 'Unknown type' .. type );
end
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return validator._error( 'Requested start is out of range' );
end
local result;
local unit;
local test_pattern;
local iterator = mw.text.gsplit(allowed_units, ",\s*");
for w in iterator do
if w == "%" then
w = "%%"
end
test_pattern=pattern .. ' *' .. mw.text.trim(w);
unit = w;
result = mw.ustring.match( s, test_pattern, start );
if result ~= nil then
break;
end
end
-- Failback 1 - Tarkistetaan onko viitteeseen loppuvaa arvoa
if result == nil and default_unit ~= nil then
unit = default_unit;
test_pattern = pattern .. " *.%'";
result = mw.ustring.match( s, test_pattern, start );
if result ~= nil then
-- korjataan test_pattern sellaiseksi ettei se riko viitettä myöhemmin
test_pattern = pattern ;
end
end
-- Failback 2 - Tarkistetaan onko eof-loppuista arvoa
if result == nil and default_unit ~= nil then
unit = default_unit;
test_pattern = pattern .. "$";
result = mw.ustring.match( s, test_pattern, start );
end
-- Failback 3 - Tarkistetaan onko eof-loppuista arvoa jos syötteestä poistetaan ensin non-breaking space
if result == nil and default_unit ~= nil then
unit = default_unit;
test_pattern = pattern .. "$";
s=mw.ustring.gsub(s, " ", "");
result = mw.ustring.match( s, test_pattern, start );
end
-- Failback 4 - Tarkistetaan onko " " loppuista arvoa
if result == nil and default_unit ~= nil then
unit = default_unit;
test_pattern = pattern .. " ";
result = mw.ustring.match( s, test_pattern, start );
end
parameter_format_message= validator._get_unit_format_message(allowed_units, number_type_str, min_value, max_value);
skip_parameter_name=parameter_name .." ohita tarkistus";
if word_delim=='_' then
skip_parameter_name=parameter_name .."_ohita_tarkistus";
end
how_to_skip_message=" – Asettamalla parametrin <code>" .. skip_parameter_name .. "=1</code> voit ohittaa tarkistuksen.";
local template_link_message='[[malline:' ..template_name ..'|' ..template_name ..']]';
-- add prefix to error results
local error_num = prefix .. " " .. s
if result == nil then
local format_error_message = 'Mallineen ' .. template_link_message .. ' parametrin <code>' .. parameter_name.. '</code> muoto <code><nowiki>' .. s .. '</nowiki></code> on virheellinen. ';
return error_num .. validator._error( format_error_message .. parameter_format_message .. error_message .. how_to_skip_message) ;
else
result=mw.text.trim(result);
result_num = validator._parse_number_str(result, min_value, max_value);
if result_num == "unknown_value_error" then
local format_error_message = 'Mallineen ' .. template_link_message .. ' parametrin <code>' .. parameter_name.. '</code> muoto <code><nowiki>' .. s .. '</nowiki></code> on virheellinen. ';
return error_num .. validator._error( format_error_message .. parameter_format_message .. error_message .. how_to_skip_message) ;
elseif result_num == "max_value_error" then
local max_value_error_message='Mallineen ' ..template_link_message .. ' parametrin <code>' .. parameter_name.. '</code> arvo <code><nowiki>' .. s .. '</nowiki></code> on suurempi kuin sallittu maksimiarvo. ';
return error_num .. validator._error( max_value_error_message .. parameter_format_message .. error_message .. how_to_skip_message ) ;
elseif result_num == "min_value_error" then
local min_value_error_message='Mallineen ' .. template_link_message .. ' parametrin <code>' .. parameter_name.. '</code> arvo <code><nowiki>' .. s .. '</nowiki></code> on pienempi kuin sallittu minimiarvo. ';
return error_num .. validator._error( min_value_error_message .. parameter_format_message .. error_message .. how_to_skip_message) ;
else
local tail = mw.ustring.gsub( s, test_pattern, "" );
return prefix .. " " .. result_num .. ' ' .. mw.text.trim(unit) .. " " .. tail ;
end
end
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function validator._getParameters( frame_args, arg_list )
local new_args = {};
local index = 1;
local value;
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index];
index = index + 1;
end
new_args[arg] = value;
end
return new_args;
end
--[[
Helper function to handle error messages.
]]
function validator._error( error_str )
local frame = mw.getCurrentFrame();
local error_category = frame.args.error_category or 'Virheellinen arvo tietolaatikossa';
local ignore_errors = frame.args.ignore_errors or false;
local no_category = frame.args.no_category or false;
if validator._getBoolean(ignore_errors) then
return '';
end
local error_str = frame:preprocess( '<ref group="virhe"><strong class="error">Tarkistusvirhe: ' .. error_str .. '</strong></ref>');
if error_category ~= '' and not validator._getBoolean( no_category ) then
error_str = '[[Category:' .. error_category .. ']]' .. error_str;
end
return error_str;
end
--[[
Helper Function to interpret boolean strings
]]
function validator._getBoolean( boolean_str )
local boolean_value;
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower();
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false;
else
boolean_value = true;
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str;
else
error( 'No boolean value found' );
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function validator._escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end
function validator._get_unit_format_message(allowed_units, number_type, min_value, max_value)
local delim="";
local allowed_units_message="";
local plural_units=false;
local iterator = mw.text.gsplit(allowed_units, ",\s*");
for w in iterator do
if delim ~= "" then
plural_units = true;
end
allowed_units_message=allowed_units_message .. delim .. "<code>" .. w .."</code>" ;
delim=", ";
end
if plural_units then
allowed_units_message = " yksikön jokin seuraavista: " .. allowed_units_message ..". ";
else
allowed_units_message = " yksikön " .. allowed_units_message ..". ";
end;
local parameter_format_message="Arvon pitäisi olla <code>" .. number_type .."</code> ja " .. allowed_units_message;
if min_value ~=nil then
parameter_format_message = parameter_format_message .. " Parametrin pienin sallittu arvo on <code>" .. min_value .."</code> ";
if max_value ~=nil then
parameter_format_message = parameter_format_message .. " ja suurin <code>" .. max_value .."</code>";
end
parameter_format_message = parameter_format_message .. ". ";
elseif max_value ~=nil then
parameter_format_message = parameter_format_message .. " Parametrin suurin sallittu arvo on <code>" .. max_value .."</code>. ";
end
return parameter_format_message;
end
return validator