Moduł:Brudnopis/Paweł Ziemian/odn

Z Wikipedii, wolnej encyklopedii

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Brudnopis/Paweł Ziemian/odn/opis

local function odnargs(args)
	return {
		[1] = args[1] or "",
		[2] = args[2] or "",
		[3] = args[3] or "",
		[4] = args[4] or "",
		[5] = args[5] or "",
		odn = args.odn or "",
		ref = args.ref ~= "nie", 
		lnk = args.linkuj ~= "nie", 
		loc = args.loc or "",
		s = args.s or args.strona or args.ss or args.strony or args.p or args.page or args.pp or args.pages or "",
	}
end

local function odnid(args)
	local odn = args.odn
	if (#odn == 0) or (odn == "tak") then
		return "CITEREF"..(args[1] or "")..(args[2] or "")..(args[3] or "")..(args[4] or "")..(args[5] or "")
	elseif (#odn == 1) and (string.byte(odn,1) >= 97) and (string.byte(odn,1) <= 122) then
		return "CITEREF"..(args[1] or "")..(args[2] or "")..(args[3] or "")..(args[4] or "")..(args[5] or "")..odn
	else
		return odn
	end
end

local function odntext(args)
	local text
	if #args[5] > 0 then
		text = args[1].." i in. "..args[5]
	elseif #args[4] > 0 then
		text = args[1]..", "..args[2].." i "..args[3].." "..args[4]
	elseif #args[3] > 0 then
		text = args[1].." i "..args[2].." "..args[3]
	else
		text = args[1].." "..args[2]
	end
	
	local odn = args.odn
	if (#odn ~= 1) or (string.byte(odn,1) < 97) or (string.byte(odn,1) > 122) then
		odn = ""
	end
	
	return text..odn
end

local function odnt(args)
	local text
	if #args[4] > 0 then
		text = args[1].." i in."
	elseif #args[3] > 0 then
		text = args[1]..", "..args[2].." i "..args[3]
	elseif #args[2] > 0 then
		text = args[1].." i "..args[2]
	else
		text = args[1]
	end
	
	return text .. (#args.year > 0 and (" "..args.year) or "")
end

local function odns(args)
	return ((#args.loc > 0) and (", "..args.loc) or "") .. ((#args.s > 0) and (", s.&nbsp;"..args.s) or "")
end

local function odnodn(args)
	local text = odntext(args)
	local id = (args.ref or args.lnk) and odnid(args)
	local s = ((#args.loc > 0) and (", "..args.loc) or "") .. ((#args.s > 0) and (", s.&nbsp;"..args.s) or "")
	return not args.lnk and (text..s) or ("<span class=\"harvard-citation\">[[#"..id.."|"..text.." ↓]]</span>"..s), id
end

local function odnparse(args)
	local ref = args.ref ~= "nie"
	local result = {}
	
	local loadGroup = function(g, i, j, year)
		mw.log("load g"..g.."i"..i.."j"..j.."year"..year)
		local last = j - i + 1
		if last > 5 then
			last = 5
		end
		
		mw.log("last"..last)
		if last < 1 then
			-- empty group or year only
			return
		end
		
		local suffix = (g > 1) and g or ""
		mw.log("suffix"..suffix)
		
		local odn = {
			[1] = (last >= 1) and args[i+0] or "",
			[2] = (last >= 2) and args[i+1] or "",
			[3] = (last >= 3) and args[i+2] or "",
			[4] = (last >= 4) and args[i+3] or "",
			year = year,
			odn = args["odn"..suffix] or "",
			lnk = false, --args["linkuj"..suffix] ~= "nie", 
			loc = args["loc"..suffix] or "",
			s = args["s"..suffix] or ((g == 1) and (args.strona or args.ss or args.strony or args.p or args.page or args.pp or args.pages) or ""),
		}
		
		mw.log("odn = "..table.concat(odn,"|"))
		local text, _ = odnt(odn)..odns(odn)

		mw.log("text = "..text)
		table.insert(result, text)
	end
	
	local g = 1
	local i = 1
	local j = 1
	while true do
		mw.log("g"..g.."i"..i.."j"..j)
		local arg = args[j]
		if not arg then
			if i < j then
				loadGroup(g, i, j-1, "")
			end
			
			break
		end
		
		local year = string.match(arg, "^%s*(%d+[a-z]?)%s*$")
		if not year and (mw.text.trim(arg) == "") then
			year = ""
		end
		
		if year then
			loadGroup(g, i, j-1, year)
			g = g + 1
			i = j + 1
		end
		
		j = j + 1
	end
	
	return table.concat(result, "\n");
end

local function odnparse2(frame)
	
	function args(name)
		local result = frame:getArgument(name)
		if result then
			return result:expand()
		end
	end
	
	function collectData(names, year)
		local count = #names
		local text
		local cite
		if count == 0 then
			text = "Brak nazwisk"
			cite = nil
		elseif count == 1 then
			text = names[1]
			cite = names[1]
		elseif count == 2 then
			text = names[1].." i "..names[2]
			cite = names[1]..names[2]
		elseif count == 3 then
			text = names[1]..", "..names[2].." i "..names[3]
			cite = names[1]..names[2]..names[3]
		else -- count == 4
			text = names[1].." i in."
			cite = names[1]..names[2]..names[3]..names[4]
		end
	
		return count, text..(#year > 0 and (" "..year) or " b.d.w."), "CITEREF"..(cite or "")..year, (cite or "!")..year
	end
	
	function retrieveDetails(group)
		if group == 1 then
			return
				args("linkuj") ~= "nie",
				args("loc") or "",
				args("s") or args("strona") or args("ss") or args("strony") or args("p") or args("page") or args("pp") or args("pages") or "",
				args("odn")
		else
			return
				args("linkuj"..group) ~= "nie",
				args("loc"..group) or "",
				args("s"..group) or "",
				nil -- forget about obsolete "odn" parameter
		end
	end
	
	local group = 0
	local refid = {}
	local outtext = {}
	local toomany = {}
	local obsolete = false
	
	function flushItem(names, year)
		group = group + 1
		local count, source, cite, id = collectData(names, year)
		local link, loc, s, odn = retrieveDetails(group)
		
		if count > 4 then
			table.insert(toomany, group)
		end
		
		if odn then
			obsolete = true
			if (#odn == 0) or (odn == "tak") then
				-- unchanged
			elseif (#odn == 1) and (string.byte(odn,1) >= 97) and (string.byte(odn,1) <= 122) then
				cite = cite..odn
				id = id..odn
				text = text..odn
			else
				cite = odn
			end
		end
		
		local where = ((#loc > 0) and (", "..loc) or "") .. ((#s > 0) and (", s.&nbsp;"..s) or "")
		
		local output
		if count == 0 then
			output = "<span style=\"color:red\">"..source.."</span>"..where
		elseif link then
			output = "<span class=\"harvard-citation\">[[#"..cite.."|"..source.." ↓]]</span>"..where
		else
			output = source..where
		end
		
		table.insert(refid, id.."?"..loc.."@"..s)
		table.insert(outtext, output)
	end

	-- scan argument list
	local names = {}
	local i = 1
	while true do
		local a = args(i)
		if not a then
			break
		end
		
		local arg = mw.text.trim(a)
		local year = string.match(arg, "^%d+[a-z]?$")
		if year or (#arg == 0) or (#arg == "b.d.w.") then
			flushItem(names, year or "")
			names = {}
		else
			table.insert(names, arg)
		end
		
		i = i + 1
	end

	-- flush last collected data
	if #names > 0 then
		flushItem(names, "")
		names = {}
	end

	-- build and append warning text
	if (#toomany > 0) or obsolete then
		table.insert(names, "<span style=\"color:red\">")
		if obsolete then
			table.insert(name, "Zastosowano przestarzałe parametry. ")
		end
		if #toomany > 0 then
			table.insert(names, "Za dużo nazwisk w grupie: ")
			for i, v in ipairs(toomany) do
				if i > 1 then
					table.insert(names, ", ")
				end
				
				table.insert(names, tostring(v))
			end
			table.insert(names, ". ")
		end
		table.insert(names, "</span>")
		table.insert(outtext, table.concat(names, ""))
	end
	
	-- create harvard citation text
	local result = table.concat(outtext, "; ")
	local tag = args("ref")
	if tag == "nie" then
		return false, result, nil
	end

	-- create citation identifier
	if not tag or (#tag == 0) then
		tag = table.concat(refid, "")
	end
	return true, result, tag
end

local function citodn(frame)
	
	function args(name)
		local result = frame:getArgument(name)
		if result then
			return result:expand()
		end
	end
	
	local odn = args("odn")
	if not odn or (#odn == 0) or (odn == "nie") then
		return nil
	elseif odn == "tak" then
		odn = ""
	elseif (#odn > 1) or (string.byte(odn,1) < 97) or (string.byte(odn,1) > 122) then
		return odn
	end

	function findName(surname, authorname)
		local name = args(surname)
		if name then
			return name
		end
		
		local author = args(authorname)
		if author then
			name = string.match(author, "([^%s]*),.*$")
			if not name then
				name = string.match(author, "([^%s]*)%s*%b()$")
			end
			if not name then
				name = string.match(author, "([^%s]*)$")
			end
		end
		
		return name or ""
	end
	
	function findYear()
		local year = args("rok")
		if not year then
			local date = args("data")
			if date then
				year = string.match(date, "%d%d%d%d")
			end
		end
	
		return year or ""
	end
	
	local name1 = findName("nazwisko r", "autor r")
	if name1 then
		return "CITEREF"..name1..findName("nazwisko2 r", "autor2 r")..findName("nazwisko3 r", "autor3 r")..findName("nazwisko4 r", "autor4 r")..findYear()..odn
	end
	
	name1 = findName("nazwisko", "autor")
	if name1 then
		return "CITEREF"..name1..findName("nazwisko2", "autor2")..findName("nazwisko3", "autor3")..findName("nazwisko4", "autor4")..findYear()..odn
	end
	
	return nil
end

return {
	id = function(frame)
		return odnid(odnargs(frame:getParent().args))
	end,
	
	text = function(frame)
		return odntext(odnargs(frame:getParent().args))
	end,
	
	odn = function(frame)
		local args = odnargs(frame:getParent().args)
		local result, id = odnodn(args)
		if not args.ref then
			return result
		end
		
		return frame:callParserFunction{ name = '#tag:ref', args = {result, name = id..args.loc..args.s} }
	end,
	
	test = function(frame)
		local args = odnargs(frame.args)
		local result, id = odnodn(args)
		return frame:callParserFunction{ name = '#tag:ref', args = {result, name = id..args.loc..args.s} }
	end,
	
	odn2 = function(frame)
		local ref, result, id = odnparse2(frame:getParent())
		if not ref then
			return result
		end
		
		return frame:callParserFunction{ name = '#tag:ref', args = {result, name = id} }
	end,
	
	citeref = function(frame)
		return citodn(frame:getParent())
	end,
	
	test2 = function(frame)
		local ref, result, id = odnparse2(frame)
	end,
	
	test3 = function(frame)
		mw.log(citodn(frame))
	end,
}