Modul:Ret oversættelse

Fra Wikipedia, den frie encyklopædi
Documentation icon Moduldokumentation[vis] [redigér] [historik] [opfrisk]

Modul:Ret oversættelse kan ændre en Wikipedia-sides kildetekst. Det er skabt til at rette typiske fejl som sker ved oversættelse af artikler fra andre Wikipediaer, herunder fjernelse af uønskede mellemrum, fjernelse af mere end en definition af samme navngivne reference, og oversættelse af indholdet i bestemte skabeloner, herunder værdien af datoparametre i kildeskabeloner.

Modulet bruges normalt som bagende for Skabelon:Ret oversættelse. Se dokumentationen for skabelonen for en liste over ting som modulet kan ændre på en side.

Brug[rediger kildetekst]

Modulet bruges normalt af skabelonen {{Ret oversættelse}}, men kan også kaldes direkte ved at indsætte

{{subst:#invoke:Ret oversættelse|ret|

allerførst på en side, og slutte af med

}}

allersidst på siden.

Modulet bruger ikke sine parametre, som skal være hele siden, som det er indsat på, men henter i stedet sidens kildetekst ved hjælp af Scribunto-biblioteket Title library. Der er ikke noget til hinder for at det kan udbygges til at acceptere yderligere parametre til at specificere hvilke type ændringer modulet skal lave, eller andet.

require("Modul:No globals")

local lang = mw.getContentLanguage()

local p = {}

local cs1_skabeloner =
{
	["Citation"] = true,
	["Kilde"] = true,
	["Cite book"] = true,
	["Kilde bog"] = true,
	["Cite web"] = true,
	["Cite www"] = true,
	["Kilde www"] = true,
	["Cite journal"] = true,
	["Kilde tidsskrift"] = true,
	["Cite news"] = true,
	["Kilde nyheder"] = true,
	["Cite encyclopedia"] = true,
	["Cite report"] = true,
	["BioRef"] = true,
}
local cs1_datoparametre =
{
	["år"] = true,
	["year"] = true,
	["date"] = true,
	["access-date"] = true,
	["accessdate"] = true,
	["archive-date"] = true,
}
local cs1_sprogparametre =
{
	['language'] = true,
	['lang'] = true,
	['sprog'] = true,
}

local engelske_sprognavne = mw.language.fetchLanguageNames('en', 'all') 
local danske_sprognavne = mw.language.fetchLanguageNames('da', 'all') 
local fundne_engelske_navne = {}
local fundne_danske_navne = {}

local function oversaet_sprog(sprog)
	mw.log ("oversaet_sprog, sprog: " .. sprog)
	if sprog:match("^%a%a%a?$") or sprog:match("^%a%a%a?%-") then
		-- sprogkode med 2 eller 3 bogstaver, evt. efterfulgt af en bindestreg og flere bogstaver
		return false
	end
	-- sprog = mw.language:lc(sprog)
	if sprog == 'hollandsk' then
		-- nl blev tidligere vist som "hollandsk", men nu "nederlandsk"
		return 'nl'
	end
	if fundne_engelske_navne[sprog] then
		mw.log ("Genfundet sprogkode " .. fundne_engelske_navne[sprog] .. " for engelsk navn " .. sprog)
		return fundne_engelske_navne[sprog]
	end
	if fundne_danske_navne[sprog] then
		mw.log ("Genfundet sprogkode " .. fundne_danske_navne[sprog] .. " for dansk navn " .. sprog)
		return false
	end
	for sprogkode, sprognavn in pairs(engelske_sprognavne) do
		if sprog == sprognavn then
			mw.log ("Fundet sprogkode " .. sprogkode .. " for engelsk navn " .. sprog)
			fundne_engelske_navne[sprog] = sprogkode
			return sprogkode
		end
	end
	for sprogkode, sprognavn in pairs(danske_sprognavne) do
		if sprog == sprognavn then
			mw.log ("Fundet sprogkode " .. sprogkode .. " for dansk navn " .. sprog)
			fundne_danske_navne[sprog] = sprogkode
			return false
		end
	end
	mw.log ("Sprog " .. sprog .. " ikke fundet")
end

local danske_maaneder =
{
	"januar", "februar", "marts", "april", "maj", "juni",
	"juli", "august", "september", "oktober", "november", "december",
	[21] = "foråret",
	[22] = "sommeren",
	[23] = "efteråret",
	[24] = "vinteren",
	[98] = "påsken",
	[99] = "julen",
}

local maaneder =
{
	Jan = 1,
	January = 1,
	Feb = 2,
	February = 2,
	Mar = 3,
	March = 3,
	Apr = 4,
	April = 4,
	May = 5,
	Jun = 6,
	June = 6,
	Jul = 7,
	July = 7,
	Aug = 8,
	August = 8,
	Sep = 9,
	September = 9,
	Oct = 10,
	October = 10,
	Nov = 11,
	November = 11,
	Dec = 12,
	December = 12,
	Spring = 21,
	Summer = 22,
	Autumn = 23,
	Winter = 24,
	Easter = 98,
	Christmas = 99
}

local function oversaet_dato(dato)
	local d, m, y
	mw.log("dato="..dato)
	if dato:match("^%d%d%d%d$") then
		-- rent årstal
		return false
	end
	if dato:match("^%d+%.%s+%a+%.?%s+%d%d%d%d$") then
		-- dansk dato med punktum: "dag. måned år" eller "dag. måned. år"
		return false
	end
	if dato:match("^%d%d%d%d%-%d%d%-%d%d$") then
		-- rent åååå-mm-dd
		return false
	end
	m, y = dato:match("^(%a+)%s+(%d%d%d%d)$")
	if m and maaneder[m] then
		-- måned og år
		return danske_maaneder[maaneder[m]] .. " " .. y 
	end
	d, m, y = dato:match("^(%d+)%s+(%a+)%s+(%d%d%d%d)$")
	if m and maaneder[m] then
		-- dag måned år
		return d .. ". " .. danske_maaneder[maaneder[m]] .. " " ..  y
	end
	m, d, y = dato:match("^(%a+)%s+(%d+),%s+(%d%d%d%d)$")
	if m and maaneder[m] then
		-- måned dag, år
		return d .. ". " .. danske_maaneder[maaneder[m]] .. " " ..  y
	end
	mw.log ("Datoformat for " .. dato .. " ikke genkendt")
	return false
end	
	
p.ret = function(frame)
	-- local args = frame:getParent().args
	local indhold = mw.title.getCurrentTitle():getContent()
    local rettelser = {}
    local advarsler = {}
    local antal
    local vis_rettelser -- Bruges p.t ikke. Kunne sættes med en parameter ...

	-- Fjern {{Ret oversættelse}}-skabelonen - hvis den har været indsat ...
	indhold, antal = string.gsub(indhold, "^%s*{{[rR]et oversættelse%s*|%s*", "")
	if antal == 1 then
		-- Den var indsat, så der må også være }}-afslutning:
		indhold, antal = string.gsub(indhold, "%s*%}%}%s*$", "")
		if antal ~= 1 then
			advarsler[#advarsler + 1] =
			"'''Advarsel:''' Det afsluttende }} i {{Vis|Ret oversættelse}}-skabelon blev ikke fundet og fjernet."
		end
	end

    -- Fjern mellemrum før punktum
    indhold, antal = string.gsub(indhold, " +%.", ".")
    rettelser[#rettelser + 1] = "Mellemrum fjernet foran punktum: " .. antal

    -- Fjern dobbelte mellemrum hvis de ikke kommer før et lighedstegn
    -- (brugt i skabeloner som infobokse med en parameter per linje)
    -- eller er først på en linje
    indhold, antal = string.gsub(indhold, "([^\n ])  +([^= ])", "%1 %2")
    rettelser[#rettelser + 1] = "Dobbelte mellemrum fjernet: " .. antal

    -- Fjern mellemrum før <ref>
    indhold, antal = string.gsub(indhold, " +<ref", "<ref")
    rettelser[#rettelser + 1] = "Mellemrum før <ref> fjernet: " .. antal

    -- Fjern mellemrum før </ref>
    indhold, antal = string.gsub(indhold, " +</ref>", "</ref>")
    rettelser[#rettelser + 1] = "Mellemrum før </ref> fjernet: " .. antal

    -- Fjern mellemrum efter startparentes
    indhold, antal = string.gsub(indhold, "%( +", "(")
    rettelser[#rettelser + 1] = "Mellemrum efter startparentes fjernet: " .. antal

    -- Fjern mellemrum før slutparentes
    indhold, antal = string.gsub(indhold, " +%)", ")")
    rettelser[#rettelser + 1] = "Mellemrum før slutparentes fjernet: " .. antal

	-- Ret navngivne referencer med forskellige definitioner
	local function reference_iterator(state, start_pos)
		local slut_pos, navn, last
		while start_pos do
			start_pos = start_pos + 1
			start_pos, slut_pos, navn, last = string.find (state, "<ref%s+name%s*=%s*(.-)%s*([/>])", start_pos)
			if start_pos and last == ">" then
				mw.log ("navn: " .. navn )
				mw.log ("navn:sub(1,1): " .. navn:sub(1,1))
				mw.log ("navn:sub(-1): " .. navn:sub(-1))
				if navn:sub(1,1) == '"' and navn:sub(-1) == '"' then
					mw.log ("Anførselstegn fjernet fra navn")
					navn = string.sub(navn, 2, -2)
				end
				local _, reference_slut, reference_tekst = string.find (state, "(.-)</ref>", slut_pos + 1)
				return start_pos, reference_slut, navn, reference_tekst
			end
		end
	end

	local navngivne_referencer = {}
	local rettetabel = {}
	for start, slut, navn, reference_tekst in reference_iterator, indhold, 0 do
		
		mw.log ("start: " .. start .. ", slut: " .. slut .. ", navn: " .. navn)
		mw.logObject (reference_tekst)
		mw.log("indhold:sub(start, slut): '" .. indhold:sub(start, slut) .. "'\n\n")
		if navngivne_referencer[navn] then
			mw.log ("dobbelt def fundet for navnet " .. navn)
			rettetabel[#rettetabel + 1] = { start=start, slut=slut, navn=navn }
		else
			navngivne_referencer[navn] = reference_tekst
		end
	end
	for i = #rettetabel, 1, -1 do
		mw.log("Retter - i: ", i, " rettetabel[i]: " .. mw.dumpObject(rettetabel[i]))
		indhold =
			indhold:sub(1, rettetabel[i].start - 1) ..
			'<ref name="' .. rettetabel[i].navn .. '"/>' ..
			indhold:sub(rettetabel[i].slut + 1)
	end
	if #rettetabel > 0 then
		rettelser[#rettelser + 1] = "Forskellige definitioner af navngivne referencer fjernet: " .. #rettetabel
	end

	-- Gennemgå sidens skabeloner og ret/oversæt parameternavne og værdier
	local function skabelon_iterator (state, start)
		local slut, skabelon, sluttegn
		if start then
			start = start + 1
			start, slut, skabelon = string.find (state, "{{%s*(.-)%s*[}|]", start)
			if skabelon then
				skabelon = lang:ucfirst(skabelon)
			end
		end
		-- returner slutposition først, så næste kald starter derfra
		return slut, start, skabelon
	end

	local function parameter_iterator (state, start)
		local slut, parameter, vaerdi
		if start then
			start = start + 1
			if state:sub(start, start) == "}" then
				-- Ikke flere parametre, skabelonen er afsluttet med "}}"
				return
			end
			start, slut, parameter, vaerdi = string.find (state, "%s*(.-)%s*=%s*(.-)%s*([}|])", start)
			-- returner slutposition først, så næste kald starter derfra
			return slut, start, parameter, vaerdi
		end
	end

	local rettetabel = {}
	local antal_oversatte_datoer = 0
	local antal_oversatte_sprog = 0
	mw.log ("Fundne skabeloner")
	for slut, start, skabelon in skabelon_iterator, indhold, 0 do
		mw.log ("Skabelon: " .. skabelon .. ", start: " .. start .. ", slut: " .. slut)
		if cs1_skabeloner[skabelon] then
			mw.log ("fundet CS1-skabelon: " .. skabelon)
			for para_slut, para_start, parameter, vaerdi in parameter_iterator, indhold, slut do
				mw.log (parameter .. "=" .. vaerdi)
				if cs1_datoparametre[parameter] then
					local dansk_dato = oversaet_dato(vaerdi)
					if dansk_dato then
						rettetabel[#rettetabel+1] =
						{ start=para_start, slut=para_slut, ny=" " .. parameter .. "=" .. dansk_dato .. " "}
						antal_oversatte_datoer = antal_oversatte_datoer + 1
						mw.log(vaerdi .. "->" .. dansk_dato)
	 				end
				elseif cs1_sprogparametre[parameter] then
					local dansk_sprognavn = oversaet_sprog(vaerdi)
					if dansk_sprognavn then
						rettetabel[#rettetabel+1] =
						{ start=para_start, slut=para_slut, ny=" " .. parameter .. "=" .. dansk_sprognavn .. " "}
						antal_oversatte_sprog = antal_oversatte_sprog + 1
						mw.log(vaerdi .. "->" .. dansk_sprognavn)
					end
				end
			end
		end
	end

	for i = #rettetabel, 1, -1 do
		mw.log("Retter - i: ", i, " rettetabel[i]: " .. mw.dumpObject(rettetabel[i]))
		indhold =
			indhold:sub(1, rettetabel[i].start - 1) ..
			rettetabel[i].ny ..
			indhold:sub(rettetabel[i].slut)
	end
	if antal_oversatte_datoer > 0 then
		rettelser[#rettelser + 1] = "Datoer oversat til dansk: " .. antal_oversatte_datoer
	end
	if antal_oversatte_sprog > 0 then
		rettelser[#rettelser + 1] = "Sprognavne oversat til dansk: " .. antal_oversatte_sprog
	end

	-- Lav den rettede udgave af siden. Tilføj advarsler, og hvis vis_rettelser er sand også en oversigt over rettelser
	mw.log("Rettelser:")
	mw.logObject (rettelser)
	local rettet_side = frame:preprocess(indhold)
	local advarselstekst = ""
	if #advarsler > 0 then
		advarselstekst = table.concat (advarsler, "<br/>") .. "<br/>"
	end
	if vis_rettelser then
		if #rettelser > 0 then
			return advarselstekst .. table.concat (rettelser, "<br/>") .. "<br/>" .. rettet_side
		else
			return advarselstekst .. "Ingen rettelser er udført<br/>" .. rettet_side
		end
	else
		return advarselstekst .. rettet_side
	end
end

return p