Spring til indhold

Modul:Formattal

Page extended-protected
Fra Wikipedia, den frie encyklopædi
Version fra 21. nov. 2017, 13:17 af Weblars (diskussion | bidrag) Weblars (diskussion | bidrag) (sørger for at et minustegn foran tallet accepteres, se fx Kuressaare#Klima)

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 inputMedEventuelleHtmlKommentarer = (frame.args[1] or "")

	-- Fjern HTML-kommentarer
    local input = string.gsub(inputMedEventuelleHtmlKommentarer, "<!%-%-.-%-%->", "") 
    -- fjern blanktegn i enderne
    input = mw.text.trim(input)
    -- fjern et evt minustegn på første position
    local i = string.find(input, '-' , 1, true )
    if i and i==1 then input = string.gsub(input, "%-", "" , 1 ) end
	-- Prøv at matche et kommatal med 1 eller 2 decimaler.
    local heltalsdel, decimaladskiller, decimaler = input: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 input med alle kommaer fjernet.
        local antalKommaerFjernet
        heltalsdel, antalKommaerFjernet = string.gsub(input, ",", "")
        
        if antalKommaerFjernet == 0 then
        	-- Der var ingen kommaer. 
	    	-- Sæt heltalsdel til input med alle punktummer fjernet i stedet.
            heltalsdel = string.gsub(input, "%.", "") 
        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).
    	-- sæt det eventuelle minustegn tilbage
	    if i and i==1 then input = '-'..input end
        return input .. fejlkategorikode
    else
    	-- Alt OK: heltalsdel indeholder nu udelukkende cifre.

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

	    if decimaler then
	        samletTal = heltalsdel .. "," .. decimaler
	    else
	    	samletTal = heltalsdel
	    end
	    -- sæt det eventuelle minustegn tilbage
	    if i and i==1 then samletTal = '-'..samletTal end
	    return samletTal
	end
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