Ugrás a tartalomhoz

Modul:CitPer

Ellenőrzött
A Wikipédiából, a szabad enciklopédiából

CitPer[mi ez?] • [dokumentáció: mutat, szerkeszt] • [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, '&#8201;&#8211;&#8201;') .. ': '
	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 = "&#x20;''" .. 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 = '&#x20;(' .. ann .. ') ' .. fasc .. ' '
	elseif outdatum and outdatum ~= '' then
		evszam = '&#x20;' .. fasc .. ' (' .. outdatum .. ') '
	elseif fasc then
		evszam = '&#x20;(????) ' .. 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 = '&#x20;' .. 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 = '&#x20;' .. 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 = '&#x20; ' .. 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    &#91; 	&#93; 	&#124;
		tit = tit:gsub('\n', ' ')
		tit = tit:gsub('%[', '&#91;')
		tit = tit:gsub('%]', '&#93;')
		tit = tit:gsub('%|', '&#124;')

		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