Modul:CitPer
Megjelenés
CitPer[mi ez?] • [dokumentáció: mutat, ] • [tesztek: létrehozás]
--Version 2020-06-19
require('strict')
local ds = require('Modul:Dátumszűrés')
local nyksz = require('Modul:Nyelvkódszűrő')
local args = {}
local used_args = {}
local lang = mw.getContentLanguage()
-- ou hibakeresésre szolgáló globális változó, ami tartalmazza az analízisre
-- szolgáló üzeneteket, az alábbi pop() függvény gyűjtögeti a tartalmát
local ou = {}
local popmax = 1000
local oumarad = popmax
local function pop(about, ...)
-- a t0rzset kell kommentbe tenni, hogy ne működjék a pop
-- idézőjeles rész és bővítmények az ou számára
--[[ memóriatúllépést okoz, csak teszteléshez
local list = { ...}
oumarad = oumarad - 1
-- előre csökkentjük, így mindig a maradék lehetséges
--pop hívások számát mutatja
if oumarad == 0 then return end -- hogy ne legyen memóriatúllépés
table.insert(ou,tostring(about).. '\n ')
for _, var in pairs(list) do
oumarad = oumarad - 1
table.insert(ou,tostring(var) .. '\n ')
mw.log(ou)
end --]]
end -- function pop(about, ...)
local hibavan = false
local hiba_jelzes = {}
local kategorizalas_van = false
local function error(kategorizalas_kell, about)
-- Enclose errorMsg with <span>
-- Precondition:
-- about -- string
hibavan = true
if kategorizalas_kell then
kategorizalas_van = true
end
local r = about
if type(about) == 'string' then
if #about == 0 then
r = 'Lua-hiba'
end
else
r = tostring(about)
end
table.insert(hiba_jelzes, '<span class="error">' .. r .. '</span>')
end
local function isRoman(v)
if type(v) ~= 'string' then
-- A római számok stringek
return false
end
if v:find('[^IVXLCDM]') then
return false
end
end
local function isArabic(v)
if type(v) ~= 'string' then
-- számok is stringek
return false
end
return (tonumber(v) ~= nil)
end
local function toRoman(num)
if num < 0 or num > 9999 then
return -1
end
local romanOnes = {'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'}
local romanTens = {'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'}
local romanHund = {'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'}
local romanThou = {'M', 'MM', 'MMM', 'MMMM', 'MMMMM', 'MMMMMM', 'MMMMMMM', 'MMMMMMMM', 'MMMMMMMMM'}
local ones = num % 10
local tens = (num - ones) % 100
local hund = (num - tens - ones) % 1000
local thou = (num - hund - tens - ones) % 10000
tens = tens / 10
hund = hund / 100
thou = thou / 1000
local romanNum = ''
if thou > 0 then romanNum = romanNum .. romanThou[thou] end
if hund > 0 then romanNum = romanNum .. romanHund[hund] end
if tens > 0 then romanNum = romanNum .. romanTens[tens] end
if ones > 0 then romanNum = romanNum .. romanOnes[ones] end
return romanNum
end
local function isISSN(str)
local v, chsum, chnum, chd, i, chnumdo
v = str:gsub('[^%dX]', '')
if #v < 8 then
return false
elseif #v > 8 then
-- csak az első 9 marad, többi ignorálva
v = v:sub(1, 8)
end
chd = v:sub(-1, -1) -- check digit az utolsó
v = v:sub(1, 7)
if chd == 'X' or isArabic(chd) then
if chd == 'X' then
chnum = 10
else
chnum = string.byte(chd, 1) - string.byte('0', 1)
end
else
return false
end
chsum = 0
for i = 8, 2, -1 do
local elsbyte = string.byte(v, 9-i)
chsum = chsum + (elsbyte - string.byte('0', 1)) * i
end
if chsum % 11 == 0 then
chnumdo = 0
else
chnumdo = 11 - (chsum % 11)
end
return (chnumdo == chnum)
end
local function getArgMain(names, le, suffix)
for _, v in ipairs(names) do
if suffix then
v = v .. tostring(suffix)
end
used_args[v] = true
if args[v] and args[v] ~= '' then
if le and type(args[v]) == 'string' then
-- lecsípjük az utolsó pontot vagy vesszőt
return args[v]:gsub('[%.,]$', '')
else
return tostring(args[v])
end
end
end
return nil
end
local function getArg(le, ...) -- itt eredetileg a frame nem paraméter
-- Retrieve template argument
-- Precondition:
-- le: true értékkel jelzi, hogy levágható a paraméter végéről a felesleges vessző és pont
-- ...: paraméternevek, az első megadott és nem üreset adja vissza
return getArgMain({...}, le)
end
local function getArgMore(le, max, ...)
local ret = {}
local val = getArg(le, ...)
if val then
table.insert(ret, val)
end
for i = 2, max do
val = getArgMain({...}, le, i)
if val then
table.insert(ret, val)
end
end
return ret
end
local function checkArgs()
for n, v in pairs(args) do
if not used_args[n] then
local msg = 'CitPer: Nem használt paraméter: ' .. n
mw.log(msg)
mw.addWarning(msg)
kategorizalas_van = true
end
end
end
local function bool(v)
return (v ~= '' and v)
end
local function urlencode(str)
-- URL kódolása
do return str end
return (str
:gsub('%s', '%%20')
:gsub('"', '%%22')
:gsub("'", '%%27')
:gsub('<', '%%3c')
:gsub('>', '%%3e')
:gsub('%[', '%%5b')
:gsub('%]', '%%5d')
:gsub('{', '%%7b')
:gsub('|', '%%7c')
:gsub('}', '%%7d')
)
end
local function _citper(conf)
local alkategoriak = {}
local s={}
local function kimenetre(x) -- éspedig így
if x then table.insert(s,x) end
end
hibavan, kategorizalas_van = false, false
hiba_jelzes = {}
used_args = {}
local honapok = {'jan.', 'feb.', 'márc.', 'ápr.', 'máj.', 'jún.', 'júl.', 'aug.', 'szept.', 'okt.', 'nov.', 'dec.'}
local aut, tit, subtit, per, ann, lun, die, datum, tom, fasc, vol, pag
local issn, doi, misc, url, lan, accd, aurl, archd, outdatum
local alkategoriak_kellenek = bool(conf['alkategóriák kellenek'])
pop('Kellenek az alkategóriák?', alkategoriak_kellenek) -- igen vagy nem a lehetséges válasz
if alkategoriak_kellenek then
if alkategoriak_kellenek == 'igen' then
pop('Kellenek az alkategóriák', alkategoriak_kellenek)
alkategoriak_kellenek = true
else
alkategoriak_kellenek = false
end
end
local sablon_kimenetek_kellenek = bool(conf['sablon kimenetek kellenek']) -- kívánságra kikapcsolható
pop('Sablon kimenetek kellenek?', sablon_kimenetek_kellenek) -- igen vagy nem a lehetséges válasz
if sablon_kimenetek_kellenek then
if sablon_kimenetek_kellenek == 'igen' then
pop('Kellenek az alkategóriák', alkategoriak_kellenek)
sablon_kimenetek_kellenek = true
else
sablon_kimenetek_kellenek = false
end
else
-- ha a getConf nil értékkel tért vissza
sablon_kimenetek_kellenek = true
end
aut = getArgMore(true, 9, 'szerző', 'aut')
tit = getArg(false, 'cím', 'tit')
subtit = getArg(false, 'alcím', 'subtit')
per = getArg(true, 'periodika', 'per')
ann = getArg(true, 'év', 'ann')
lun = getArg(true, 'hónap', 'lun')
die = getArg(true, 'nap', 'die')
datum = getArg(true, 'dátum', 'date')
fasc = getArg(true, 'szám', 'fasc')
vol = getArg(true, 'kötet', 'volume')
url = getArg(false, 'url')
lan = getArg(true, 'nyelvkód', 'lan')
accd = getArg(true, 'elér', 'accd')
issn = getArg(true, 'issn')
pag = getArg(true, 'oldal', 'pag')
archd = getArg(true, 'archívdátum', 'archd')
aurl = getArg(true, 'archívurl', 'aurl')
doi = getArg(true, 'doi')
tom = getArg(true, 'évfolyam', 'tom')
misc = getArg(true, 'egyéb', 'misc')
--szerzők
---[=[ -- a szerzőket előre lépteti, társszerzőből szerzőt csinál stb.
if #aut > 0 then
aut = table.concat(aut, ' – ') .. ': '
else
aut = nil
end
--]=]
--cím és alcím
local terminator
if tit then
tit = mw.text.trim(lang:ucfirst(tit))
pop('cím', tit)
else
tit = ' (cím nélkül) '
end
if subtit then
subtit = lang:ucfirst(subtit)
-- ha a cím végén kettőspont van, leszedjük, hogy ne legyen kettő egymás után
tit = tit:gsub(':$', '') .. ': ' .. subtit
end
if not tit:match('[%.%?!,\166]$') then
tit = tit .. '.'
end
-- periodika
if per and per ~= '' then
per = " ''" .. per .. ",'' "
elseif tit and tit ~= '' then
error(false, 'periodika nélkül')
end
if ann then
ann = ann:gsub('[%[%]]', '')
local count
ann = ann:gsub('[%-]', '–') -- kiskötőjelből nagy kötőjel
ann, count = ann:gsub('[^%–0123456789]', '') -- az évben csak számjegyek és nagy kötőjel maradhat
pop('év a gsubot követően', ann)
if count ~= 0 then
error(true, 'tiltott karakter az év paraméterben')
table.insert(alkategoriak, '[[Kategória:Hibásan használt CitPer – tiltott karakter az év paraméterben]]')
end
local nums = {} -- évszámok tárolása
local hossz = {} -- évszámok számának tárolása
-- csak (arab) számjegyeket keres
for w in ann:gmatch('%d+') do
table.insert(nums, w)
table.insert(hossz, #w)
end
pop('hány tagból áll az év?', #nums)
if #nums == 2 then
-- lásd almanachok 2011–2012
pop('évtag 1', nums[1])
pop('évtag 2', nums[2])
if hossz[1] == hossz[2] then
datum = nil
-- és most bármi volt a két év adat közt az inputban, nagykötőjel köti össze őket
ann = nums[1] .. ' – ' .. nums[2]
end
else -- p. éééé-éé az év megadásának formája
-- nem tekintjük az éééé-hh forma szándékának, levágjuk
datum = ann:sub(1, 4) .. '.'
pop('dátum évből1', datum)
if lun then
lun = lun:gsub('[%[%]]', '')
if tonumber(lun) then
lun = honapok[tonumber(lun)]
pop('hónap mint szám', lun)
end
if lun then
datum = datum .. ' ' .. lun
pop('dátum évből, hóból', datum)
if die then
die = die:gsub('[%[%]]', '')
datum = datum .. ' ' .. die .. '.'
pop('dátum évből, hóból, napból', datum)
end
else
error(false, 'hibás hónap')
end
end
-- már összeállt a dátum
ann = nil
end
end
-- DÁTUM
-- ha van dátum (most már vagy a dátum, vagy ennek hiányában az év)
if datum then
datum = datum:gsub('[%[%]]', '')
local nyom, dou = ds.datumszuro(datum)
pop('nyom', nyom)
pop('dou', tostring(dou))
if dou then
outdatum = ds.honapnevesdate(dou) -- zárójelezés a szám és év sorrend tisztázásánál
pop('outdatum', outdatum)
else
-- bármit adtak meg, menjen a kimenetre (az outdatum körül még nincs zárójel)
outdatum = datum
error(false, 'hibás dátum')
end
pop('*outdatum', outdatum)
end
if fasc then
fasc = fasc:gsub('-', '–')
fasc = fasc:gsub('—', '–')
fasc = fasc .. '. sz.'
pop('*szám=', fasc)
end
local evszam = ''
if not fasc then
-- ha a szám nil érték, akkor legyen üres a konkatenálás miatt
fasc = ''
end
if ann then
evszam = ' (' .. ann .. ') ' .. fasc .. ' '
elseif outdatum and outdatum ~= '' then
evszam = ' ' .. fasc .. ' (' .. outdatum .. ') '
elseif fasc then
evszam = ' (????) ' .. fasc .. ' '
end
pop('evszam', evszam)
-- évfolyam
if tom then
if not isRoman(tom) then
if isArabic(tom) then
tom = toRoman(tonumber(tom))
end
end
tom = ' ' .. tom .. '. évf.'
end
-- oldal
if pag then
pag = pag:gsub('-', '–') -- kiskötőjelből nagy
pag = pag:gsub('—', '–') -- hetvenkvirtesből nagy
pag = pag:gsub('%.,', ',') -- pontot követő veszőből vesszőt
pag = pag:gsub('%.', '') -- pontból üreset
pag = pag:gsub(',', '.,') -- végül vesszőből ponot követő vesszőt
pag = ' ' .. pag .. '. o.'
end
-- ISSN
if issn then
if isISSN(issn) then
issn = issn:sub(1, 9)
issn = '[https://www.worldcat.org/search?q=n2:' .. issn .. ' ISSN ' .. issn .. ']'
else
error(true, 'hibás ISSN')
end
end
-- archívdátum -- archívurl
if archd then -- ha van dátum
archd = archd:gsub('[%[%]]', '')
local outarchd, dou
dou = select(2, ds.datumszuro(archd))
if dou then
outarchd = ds.honapnevesdate(dou)
if aurl then
aurl = urlencode(aurl)
archd = '<span title="' .. outarchd .. '">[' .. aurl .. ' arch]</span>'
else
error(true, 'archívdátum van, de archívurl nélkül')
-- table.insert(alkategoriak, '[[Kategória:Hibásan használt CitPer – archívdátum archívurl nélkül]]')
end
else
error(true, 'hibás archívdátum')
-- table.insert(alkategoriak, '[[Kategória:Hibásan használt CitPer – hibás archívdátum]]')
end
end
-- DOI
if doi then
local doicontrol, doi_10_utani_resz
doicontrol = doi:sub(1, 2)
doi_10_utani_resz = doi:sub(3, -1)
if doicontrol ~= '10' then
doi = '10' .. doi_10_utani_resz
end
doi = '<span title="' .. doi .. '">[https://dx.doi.org/' .. doi .. ' doi]</span>'
end
-- kötet
if vol then
vol = ' ' .. vol .. ' k.'
end
--egyéb
if misc then
misc = '  ' .. misc
end
-- url
if url ~= nil then
-- SZÜKSÉGES CSERÉK:cím=[http://crypto.com/papers/jbug-Usenix06-final.pdf Keyboards and Covert Channels"]
--newline [ ] | Ezek kellenek, mert az URL ráhúzásakor bezavarnak
--space [ ] |
tit = tit:gsub('\n', ' ')
tit = tit:gsub('%[', '[')
tit = tit:gsub('%]', ']')
tit = tit:gsub('%|', '|')
url = urlencode(url)
tit = '[' .. url .. ' ' .. tit .. ']'
-- http://mek.oszk.hu/00300/00355/html/ABC11587/12167.htm| Bányadémon és bergmandl: Mi van, ha alcím is van?
end
-- nyelv kezelése
if lan then
local nyelvek,hibak,nyomok = nil
nyelvek,hibak,nyomok = nyksz.nyelvszuro(lan)
if hibak then
pop("kapott hibalista=", nyomok)
error(true, hibak ..'hibás nyelvkód')
table.insert(alkategoriak, 'Hibásan használt CitPer – nyelvkódhiba')
end
if nyelvek then
pop("kapott nyelvlista=", nyelvek)
lan = nyelvek
end
if nyomok then
pop("nyomkövetés a nyelvszűrésen belül=", nyomok)
end
if not per or per == '' then
error(true, 'nyelv periodika nélkül')
table.insert(alkategoriak, 'Hibásan használt CitPer – nyelv periodika nélkül')
end
end --if lan
-- elérés dátuma
if accd then
accd = accd:gsub('[%[%]]', '')
local nyom, dou = ds.datumszuro(accd)
pop('a dátumszűrés eredménye', nyom)
if dou then
accd = 'Hozzáférés: ' .. ds.honapnevesdate(dou)
else
error(false, 'hibás elérési dátum')
end
end
-- figyelmeztetés a megadott, de nem használt paraméterekre
checkArgs()
-- az output összeállítása
if sablon_kimenetek_kellenek then
kimenetre( aut )
kimenetre(tit )
kimenetre(lan )
kimenetre(per )
kimenetre( tom )
kimenetre( vol )
kimenetre(evszam )
kimenetre(pag )
kimenetre( archd )
kimenetre( issn )
kimenetre(doi )
kimenetre(accd )
kimenetre(misc )
if ou and (#ou ~= 0) then kimenetre( table.concat(ou,'{*}')) end -- ez csak nyomkövetésre
end -- sablon kimenetek kellenek
if hibavan then kimenetre( table.concat(hiba_jelzes, ', ')) end
if kategorizalas_van then kimenetre('[[Kategória:Hibás paraméterezésű CitPer sablont tartalmazó lapok]]')
end
if alkategoriak_kellenek and (#alkategoriak > 0) then
kimenetre ('[[Kategória:'..table.concat(alkategoriak, ']] [[Kategória:')..']]')
end
return mw.text.trim(table.concat(s, ' '))
end -- function _citper
local function _run(a, c)
args = a
return _citper(c or {})
end
local function run(frame)
local pframe = frame:getParent()
args = pframe.args -- a sablon hívásakor megadott paraméterek
return _citper(frame.args) -- az #invoke utasításban átadott paraméterek
end
local p = {
run = run,
_run = _run
}
return p