Die Dokumentation für dieses Modul kann unter Modul:Benutzer:Kpfiwa/calc/Doku erstellt werden

--[=[ calc Version 1b BETA, 2020-007-06
	project management: [[:de:User:Gadacz]]
	Should still be thoroughly "cleaned" and optimized.
	Due the different language versions only after consultation.
	Various extensions planned (number formatting, attributes, alignment, more 
	calculation options, e.g.: item no/rank {# {1}} and much more

	© „CC-by-sa 4.0“
--]=]
--[[
mw.getContentLanguage().code -- Returns the content language.
mw.getCurrentFrame():preprocess("{{PAGELANGUAGE}}") -- Returns the page language.
mw.getCurrentFrame():preprocess( "{{int:Lang}}" ) -- Returns the user language
(if the wiki has created the messages needed to support this feature).
--]]
local ERR="ERR=\n"
local p = {} -- transfer array
text, result1, result2 , txt= '',{}, {}, '' -- for interim results
local regexg = "%{([^{]-)%{.*" -- extract group sign
local regexv = "%{[^{]-%{([%d-+*/^|]*)}}" -- AKTUELL NUR ZAHLENWERTE! extract value (number or 'sum', 'avg', 'min', 'max', numbers in combinations)

local function loadlanguage() --
	local lang = mw.getContentLanguage():getCode()
	local list = "Modul:Benutzer:Gadacz/calc/lang"
	return mw.loadData(list)
--[[
local l10n = l10na[mw.language.getContentLanguage():getCode()]
if not l10n then
    l10n = l10na.en
end
-- say = l10n.msgA --]]
end -- function loadlanguage()

local function tu(a,z) --[[ converts a to uppercase and extracts the first character
				or z number of characters --]]
	if not a then return '' end
	return string.sub(string.upper(a), 1, z or 1)
end -- function tu(a,z)

local function tl(a,z) --[[ converts a to lowercase and extracts the first character
				or z number of characters --]]
	if not a then return '' end
	return string.sub(string.lower(a), 1, z or 1)
end -- function tl(a,z)

local function nodub(s, c) -- remove twice chars & evtl use c (as center)
    local ret = ""
    if not c then c = "" end -- if not c then empty string
    if string.find(s, "l") and string.find(s, "r") then
        s = string.gsub(s, "[lr]+", c) -- left & right = center (or '')
    end
    if not string.find(s, "l") and not string.find(s, "r") then
        s = s .. c -- if given param c then use center as default
    end 
    for char in string.gmatch(s, ".") do -- separate the string into single letters
        if not string.find(ret, char) then -- to avoid 2 same chars
            ret = ret .. char
        end 
    end -- for char
    return ret
end
local function tonum(ein) -- converts numbers entered differently
	local erg, stat = '',0
	erg, stat = string.gsub(ein, "(%D*)([%s%-%d,%.%']+)(%D*)", "%1|%2|%3") 
	if stat > 0 then
		nix, erg ,nix = string.match(erg, "(.*)|(.*)|(.*)")
		erg=string.gsub(string.reverse(erg), "[%.,]+", "QIX",1) -- QIX = temp dummy wo any risk of confusion
		erg=string.gsub(erg, "[%.,%s%']+", "")
		erg=string.reverse(string.gsub(erg, "QIX", "."))*1
	end -- if stat
	return erg, ein
end -- function tonum(ein

local function emph(what) -- emphasis, typeface for the text acc. template parameters 'd = ...' (decoration)
	local css = ''
	if not what or #what < 1 then return '' end -- undecorated return
    if #what <= 6 then -- what is larger will be a directly entered css statement
        what = nodub(tl(what,6),'c')
        for e in string.gmatch(what , ".") do -- separate if several parameters
            if e == 'f' or e == 'b' then css = css .. " font-weight:bold;"
              elseif e == 'k' or e == 'i' then css = css .. " font-style:italic;" -- german kursiv
              elseif e == 'u' then css = css .. " text-decoration:underline;"
              elseif e == 'v' or e == 'g' then css = css .. " text-transform:uppercase;"  -- german versal
              elseif e == 's' then css = css .. " font-variant:small-caps;"
              elseif e == 'l' then css = css .. " text-align:left;"
              elseif e == 'r' then css = css .. " text-align:right;"
              elseif e == 'c' then css = css .. " text-align:center;"
            end -- if e
        end -- for e
      else -- if #what
        what = string.gsub(what,"['%\"]+",'')  -- possibly remove quotation marks
        css = string.gsub(what,"[%w]+%s*=%s*",'') -- if accidentally started with 'string ='
    end  -- if #what
   return css
end -- function emph(what)


--[[ NICHT FÜR de:WP!!! Da gab es Löschung von Vorlage:Coltab, aus der die Farbgebung stammt
	function hsv2rgb(h,s,v)
	function val2hsv(val, max, min, gb)
--]]

function groupname(a) -- extract group for calculations
	ret = string.match(a,'([^{^}]+)')  --regex for group-name [a-z0-9] in {?{
	return tl(ret)
end

function nullern(z)
---local z=string.gsub(z,"^(%0+)",'<span style="visibility:hidden;">%1</span>')
return z
end

function xxtester()
	local osEnv = {}
 ret=''
for line in io.popen("set"):lines() do 
  envName = line:match("^[^=]+")
  osEnv[envName] = os.getenv(envName)
  --print(envName,osEnv[envName] )
 ret = ret  .. line .. '######' .. envName ..'<br>'

end
  --ret = ret ..   envName..'######' .. osEnv[envName] .. '\n'
  return ret
  end
function nowiex(txt,  frame) --[[ unstrip nowiki & process all including templates.
								Calculation instructions that contain a pipe as 
								parameter separator e.g. "{a {123 | format =., 0 | deko = ubi}}"
								cause problems with 'preprocess'; hence exchange
								of the pipe delimiter to @ --]]

local ord
    --txt = mw.text.unstripNoWiki(txt) -- problems with <ref>!!
    txt = mw.text.unstrip(txt) -- problems with <ref>!!
    for ord in string.gmatch(txt, "%{.%{[^|^}]+%|[^}]*}}") do
        txt = string.gsub(txt, ord, string.gsub(ord, "%|", "@"))
    end -- for ord
    txt = string.gsub(txt, "||", "\n|") -- Doppelpipes in Tabellen umsetzen
    txt = string.gsub(txt, "&lt;", "<")
    txt = string.gsub(txt, "&gt;", ">")
    return frame:preprocess(txt)
end --function nowiex


function rank(txt)
 local s2 = "%{#%{[@#]*%w+=[^}]+}}"
    local s3 = "(%w+)=(%w+)"  --[[ QIX hier vielleicht noch Startnimmde (default 1) vorgeben {#{10|d=b}} oder sogar übernahme der letzten nummer aus der vortabelle --]]
    local a, replace = 1,''
    emp = string.lower(string.match(txt, s2) or "c")
    if emp then
        fd, emp = string.match(emp, s3)
        emp = emph(emp)
    end -- if emp
txt = string.gsub(txt, s2, "") -- delete 1st form/disp definition



    --local sgsub = "|[^%-]([^|]*)|*%s*{#{#*}}"
    local sgsub = "|[^%-]([^|]*)|*%s*{#{#*}}%s*|"
    local sgmatch = "|[^%-][^|]*|*%s*{#{#*}}"
    local nr = 1
    for _ in string.gmatch(txt, sgmatch) do
        -- txt = string.gsub(txt, sgsub, "| " .. emp .. "%1" .. " | " .. nr, 1)
        txt = string.gsub(txt, sgsub, "<td " .. emp .. "%1" .. ">" .. nr .. '</td>', 1)
        nr = nr + 1
    end
    return txt
end


--[=[ function p.f(frame)
		* Evaluation
			** Calculation of the color value via val2hsv and hsv2rgb - NICHT FÜR de-WP
			** Composition of the field content in the table including
				formatting and coloring instructions. - NICHT FÜR de:WP
		* Return of the result as an array (Lua table)
		!! Note: The identifiers for the parameters are reduced to the first
		letter and changed to upper case
		Lower case is meaningless, the identifier can be chosen as long as the
		first letter is unique
		Parameter:
		@param 1 or  named-key = 'V'alie  oder  de:'W'ert
			transfer of the text to be evaluated.
			If the text contains pipes, especially tables,
			the transferred text must be included in <nowiki> ... </nowiki>
		@param 2 oder 'F'ormat
			Specification of formatting numerical values to be used:
			thousands separator, decimal separator, preceding minus, identifier (€ % $ km² ...)
		@param 'O'rientation if different from general specification of table
			O=L -> left-justified
			O=R -> right-justified
			O=Z oder O=C -> centered :de:zentriert
			O=D Alignment with decimal point/-comma (# of dec places if necessary)
		@param 'A'ttribute: addition like 'style = ', colspan, rowspan, class ... 
		@param 'C'ontrast, <100 fades -- NICHT FÜR de-WP!!!
--]=]
function   printtab(tabl)
	local ret,vat='',''
	for ka, va in pairs(tabl) do
	--	ret=ret .. ka .. " VAL=" .. vat .. "<br>\n"
		ret=ret .. " VAL=" .. ka .. "<br>\n"
	end
	return ret
end

function p.f(frame)
	local numval, maximum, kontrast, hell , minimum = 0, 10, 25, 100, 0
	local stringval, orient, anhang, sort, erg , class, css, style = '', '', '', '', '', '','', ''
	local ft
	frame = frame:getParent() -- first call up the transferred parameters
	for key, val in pairs(frame.args) do -- assign individual parameters
		key = tu(key) -- convert/shorten all parameters to one capital letter
		if key == "1" or key == 'V' or key == 'W' then text = nowiex(val,frame) -- frame:preprocess(mw.text.unstripNoWiki(val))-- ; txt='</nowiki>' .. text-- processes all contained templates into values
		--if key == "1" or key == 'V' or key == 'W' then text = templatevalues(val) -- processes all contained templates into values
		elseif key == "2" or key == 'F' then format = val --[[ General formatting
    			of the numbers (# of digits, decimal places, signs, characters,
    			such as $ € km³ % ... --]]
		end -- if key
	end -- for key
	--[[ The now translated text (template evaluation) is searched for "{? [...}}""
		and the instructions specified there are executed.
		Then the processed text with the calculation results is transferred
		to the function call. --]]
-- calculate and display rank col 
text = rank(text)
-- https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/de#mw.language:parseFormattedNumber
-- evtl: https://me-pedia.org/wiki/Module:Languages
local l1=mw.language.getContentLanguage()
local l2=mw.getContentLanguage() 
local yyy =l1:getCode()
local q1='{| class="wikitable"'
q1= q1 .. string.format ("\n|-\n|Preceding with blank||%10.2f", 19.77)
q1=q1 .. string.format ("\n|-\n|Preceding with zeros|| %010.2f", 19.77)
q1=q1 .. string.format ("\n|-\n|floats|| %14.2f %+.0f %-4.2f %-4.2f", 3.1416, 3.1416, -3.1416, 3.1416)
q1=q1 .. "\n|-\n|123||!1234567890!"
q1=q1 .. "\n|-\n|000||!0000000000!"
q1=q1 .. '\n|-\n|nbs||style="white-space: pre"|!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!'
q1=q1 .. '\n|-\n|nbs+lz||style="white-space: pre"|!&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!'
q1=q1 .. '\n|-\n|lz pre-wrap||style="white-space: pre-wrap"|!          !'
q1=q1 .. '\n|-\n|nullern||'.. nullern(000123456)
q1=q1 .. '\n|-\n|nullern||'.. nullern(000001236)
q1=q1 .. '\n|-\n|formatNum||'.. l1:formatNum( 12345487.999 )
q1=q1 .. '\n|-\n|formatNum000||'.. l1:formatNum( 00012345487.99 )
q1=q1 .. '\n|-\n|formatNum++000||'.. l1:formatNum( -00012345487.9879 )
q1=q1 .. '\n|-\n|l2||'.. printtab(l2)

q1 = q1 .. "\n|}"
local l1=mw.language.getContentLanguage()
local l2=mw.getContentLanguage() 
return text,q1
end -- function p.f(frame)

return p