Spring til indhold

Modul:Formattal

Page extended-protected
Fra Wikipedia, den frie encyklopædi
Version fra 22. nov. 2017, 22:14 af Jhertel (diskussion | bidrag) Jhertel (diskussion | bidrag) (Ingen grund til at fjerne %-tegn også :-). Ændringen er så lille, at jeg vælger ikke at teste i sandkasse først.)

local p = {}
local fejlkategorikode = "[[Kategori:Sider med tal hvis format ikke kendes af formattal]]"

--[[
  formattal(frame)
  
  Formaterer et ikke-negativt tal med højst to decimaler på dansk. Det 
  oprindelige tal kan enten bruge punktum som decimaladskiller og komma som 
  tusindadskiller ("123,456,789.12"), eller komma som decimaladskiller og 
  punktum som tusindadskiller ("123.456.789,12").
  
  Uanset hvordan tallet var formateret i input, formateres det i output på dansk
  vis med punktum som tusindadskiller og komma som decimaladskiller.
  
  Eksempler:
    Opfattes som 6-cifret heltal, da tallet ikke må have mere end to decimaler:
      formattal("123456") = "123.456"
      formattal("123,456") = "123.456" 
      formattal("123.456") = "123.456"
    Opfattes som 5-cifret tal med 2 decimaler:
      formattal("123,45) = "123,45"
      formattal("123.45") = "123,45"
    Giver fejl for ukendt format (negativt tal):
      formattal("-123") = "-123"
    Giver fejl for ukendt format (tusindadskiller og decimaltegn er ens):
      formattal("123.456.7") = "123.456.7" 
    Giver fejl for ukendt format (bruger forskellige tusindadskillere eller
    har for mange decimaler):
      formattal("123.456,789") = "123.456,789"

  Alle HTML-kommentarer og visse blanktegn i tallet ignores; andre uvedkommende
  tegn vil give fejl.

  Ved fejl returneres tallet uændret samtidig med at artiklen placeres i 
  fejlkategorien "Sider med tal hvis format ikke kendes af formattal".
]]
function p.formattal (frame)
    local originaltInput = (frame.args[1] or "")

	-- Fjern HTML-kommentarer
    local inputUdenEventuelleHtmlKommentarer 
    	= string.gsub(originaltInput, "<!%-%-.-%-%->", "") 

    -- Fjern blanktegn i enderne
    local inputUdenEventuelleHtmlKommentarerOgBlanktegn 
    	= mw.text.trim(inputUdenEventuelleHtmlKommentarer)

    -- Fjern et evt minustegn på første position og husk det.
    local eventueltMinustegn, inputUdenEventueltMinustegn 
    	= p.fjernEventueltIndledendeMinustegnOgReturnerDetOgReststrengen(inputUdenEventuelleHtmlKommentarerOgBlanktegn)

	-- Prøv at matche et kommatal med 1 eller 2 decimaler.
    local heltalsdel, decimaladskiller, decimaler 
    	= inputUdenEventueltMinustegn:match("^%s*(.-)([,%.])(%d%d?)%s*$")

    if decimaladskiller then
    	-- Decimaladskiller fundet: Tallet er et kommatal med 1 eller 2 decimaler.
        if decimaladskiller == "." then
        	-- Decimaladskiller er punktum.
        	-- Fjern alle kommaer fra heltalsdel.
            heltalsdel = string.gsub(heltalsdel, "[,]", "") 
        else
        	-- Decimaladskiller er komma.
        	-- Fjern alle punktummer fra heltalsdel.
            heltalsdel = string.gsub(heltalsdel, "[.]", "")
        end
    else
    	-- Decimaladskiller ikke fundet. Tallet er et heltal.
    	
    	-- Sæt heltalsdel til inputUdenEventueltMinustegn med alle kommaer fjernet.
        local antalKommaerFjernet
        heltalsdel, antalKommaerFjernet = string.gsub(inputUdenEventueltMinustegn, ",", "")
        
        if antalKommaerFjernet == 0 then
        	-- Der var ingen kommaer. 
	    	-- Sæt heltalsdel til inputUdenEventueltMinustegn med alle punktummer fjernet i stedet.
            heltalsdel = string.gsub(inputUdenEventueltMinustegn, "%.", "") 
        end
    end

	-- Fjern alle blanktegn (whitespace) fra heltalsdel
    heltalsdel = string.gsub(heltalsdel, "%s", "")

    if string.match(heltalsdel, "%D") then
    	-- Fejlsituation: Heltalsdel indeholder mindst ét ikke-ciffer (%D).
        return inputUdenEventuelleHtmlKommentarerOgBlanktegn .. fejlkategorikode
    else
    	-- Alt OK: heltalsdel indeholder nu udelukkende cifre.

    	-- Indsæt tusindadskillere i heltalsdel.
    	heltalsdelMedTusindadskillere = p.indsaetTusindadskillere(heltalsdel)
        
		-- Sammensæt det samlede tal fra heltalsdel og eventuelle decimaler.
	    local samletTal
        local heltalsdelMedTusindadskillereOgEventueltMinustegn 
        	= eventueltMinustegn .. heltalsdelMedTusindadskillere

	    if decimaler then
	        samletTal = heltalsdelMedTusindadskillereOgEventueltMinustegn .. "," .. decimaler
	    else
	    	samletTal = heltalsdelMedTusindadskillereOgEventueltMinustegn
	    end

	    return samletTal
	end
end

function p.fjernEventueltIndledendeMinustegnOgReturnerDetOgReststrengen(s)
    local eventueltMinustegn, sUdenMinustegn
    
    local i = string.find(s, '-' , 1, true)

    if i==1 then  
    	-- Der er et minus på første position.
    	eventueltMinustegn = "-"
    	reststrengUdenMinustegn = string.gsub(s, "%-", "" , 1)
    else
    	-- Der er ikke et minus på første position.
    	eventueltMinustegn = ""
    	reststrengUdenMinustegn = s
    end

	return eventueltMinustegn, reststrengUdenMinustegn
	
end

--[[
	p.indsaetTusindadskillere(heltalsStreng)
	
	Hjælpefunktion. 
	
	Indsæt tusindadskillere i en given streng af cifre.

	Eksempler:	
		p.indsaetTusindadskillere("") == ""
		p.indsaetTusindadskillere("1") == "1"
		p.indsaetTusindadskillere("12") == "12"
		p.indsaetTusindadskillere("123") == "123"
		p.indsaetTusindadskillere("1234") == "1.234"
		p.indsaetTusindadskillere("123456789") == "123.456.789"
]]
function p.indsaetTusindadskillere(heltalsstreng)
	local akkumulator = heltalsstreng -- Heltal uden tusindadskillere, fx "123456789".
	local antalTusindAdskillereIndsat

    repeat  
        akkumulator, antalTusindAdskillereIndsat 
        	= string.gsub(akkumulator, "^(%d+)(%d%d%d)", '%1.%2')
    until antalTusindAdskillereIndsat == 0

    return akkumulator  -- Heltal med tusindadskillere, fx "123.456.789".
end

return p