Moduł:Brudnopis/ToasterCoder/Pasjans

Z Wikipedii, wolnej encyklopedii

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

local p = {}

local function decodeExpr(value, W, H, w, h) -- Rozwiązywanie wyrażeń pozycji
	local keywords = "GgWHwhxy" -- słowa kluczowe
	local nums = "0123456789" -- liczby
	
	local cardVars = { -- Wartości słów kluczowych
		G = 10, -- margines wewnątrz planszy
		g = 4, -- odstęp między kartami
		W = W, -- szerokość planszy
		H = H, -- wysokość planszy
		w = w, -- szerokość karty
		h = h, -- wysokość karty
		x = 12, -- szerokość liczby/litery za rogiem karty
		y = 16 -- wysokość liczby/litery za rogiem karty
	}
	
	local frac1 = "" -- licznik/liczba
	local frac2 = "" -- mianownik
	local kw = "" -- słowo kluczowe
	local stage = "frac1" -- etap
	local minus = false -- dodawanie/odejmowanie
	local result = 0 -- wynik do zwrócenia
	
	for i = 1, mw.ustring.len(value) do
		if stage == "frac1" then
			if mw.ustring.find(nums, mw.ustring.sub(value, i, i), 1, true) then
				frac1 = frac1 .. mw.ustring.sub(value, i, i)
			elseif mw.ustring.sub(value, i, i) == "/" then
				stage = "frac2"
			elseif mw.ustring.find(keywords, mw.ustring.sub(value, i, i), 1, true) then
				frac2 = "1"
				kw = mw.ustring.sub(value, i, i)
				if minus == false then
					result = result + (tonumber(frac1) / tonumber(frac2) * cardVars[kw])
				elseif minus == true then
					result = result - (tonumber(frac1) / tonumber(frac2) * cardVars[kw])
				end
				stage = "add"
			end
		elseif stage == "frac2" then
			if mw.ustring.find(nums, mw.ustring.sub(value, i, i), 1, true) then
				frac2 = frac2 .. mw.ustring.sub(value, i, i)
			elseif mw.ustring.find(keywords, mw.ustring.sub(value, i, i), 1, true) then
				kw = mw.ustring.sub(value, i, i)
				if minus == false then
					result = result + (tonumber(frac1) / tonumber(frac2) * cardVars[kw])
				elseif minus == true then
					result = result - (tonumber(frac1) / tonumber(frac2) * cardVars[kw])
				end
				stage = "add"
			end
		elseif stage == "add" then
			if mw.ustring.sub(value, i, i) == "+" then
				minus = false
			elseif mw.ustring.sub(value, i, i) == "-" then
				minus = true
			end
			frac1 = ""
			frac2 = ""
			kw = ""
			stage = "frac1"
		end
	end
	return tostring(result)
end

local function decodeCardArg(value, W, H, w, h) -- value -> <index><color>,<x>,<y>,<rotate deg>,<originx>,<originy>
	local splitted = {}
	
	local temp = ""
	for i = 1, mw.ustring.len(value) do
		if mw.ustring.sub(value, i, i) == ";" then
			table.insert(splitted, temp)
			temp = ""
		else
			temp = temp .. mw.ustring.sub(value, i, i)
		end
	end
	
	splitted[2] = decodeExpr(splitted[2], W, H, w, h)
	splitted[3] = decodeExpr(splitted[3], W, H, w, h)
	
	if splitted[4] and splitted[5] and splitted[6] then -- jeśli karta obrócona względem konkretnego punktu
		splitted[5] = decodeExpr(splitted[5], W, H, w, h)
		splitted[6] = decodeExpr(splitted[6], W, H, w, h)
	end

	return splitted
end

local function makeCard(arg, width, height, cwidth, cheight, cscale)
	local data = decodeCardArg(arg, width, height, cwidth * cscale, cheight * cscale)
	local card = mw.html.create("div")
		:css("position", "absolute")
		:css("transform", "scale(" .. cscale .. ")")
		:css("left", data[2] - cwidth / 2 .. "px")
		:css("top", data[3] - cheight / 2 .. "px")
	
	if data[4] then
		rotateBox = card:tag("div")
			:css("transform", "rotate(" .. data[4] .. "deg)")
		if data[5] and data[6] then
			rotateBox:css("transform-origin", (data[5] - data[2] + cwidth * cscale / 2) / cscale .. "px " .. (data[6] - data[3] + cheight * cscale / 2) / cscale .. "px")
		end
		rotateBox:wikitext("[[Plik:Minicard " .. data[1] .. ".svg|" .. cwidth .. "x" .. cheight .. "px|alt=|link=]]")
	else
		card:wikitext("[[Plik:Minicard " .. data[1] .. ".svg|" .. cwidth .. "x" .. cheight .. "px|alt=|link=]]")
	end
	return tostring(card)
end

local function innerboard(args, pargs, width, height, cwidth, cheight, cscale)
	local box = mw.html.create("div")
		:css("position", "relative")
	local i = 1
	while args[i] or pargs[i] do
		box:wikitext(makeCard(args[i] or pargs[i], width, height, cwidth, cheight, cscale))
		i = i + 1
	end
	return tostring(box)
end

function p.board(frame)
	local args = frame.args
	local pargs = frame:getParent().args
	
	local caption = args.caption or pargs.caption or ""
	local alt = args.alt or pargs.alt or caption
	local align = (args.align or pargs.align or "tright"):lower()
	local width = args.width or pargs.width or "8w"
	local height = args.height or pargs.height or "5h"
	
	local cwidth = 57 -- szerekość karty w commons
	local cheight = 88 -- wysokość karty w commons
	local cscale = 0.6 -- rozmiar karty w szablonie
	
	width = decodeExpr(width, 0, 0, cwidth * cscale, cheight * cscale)
	height = decodeExpr(height, 0, 0, cwidth * cscale, cheight * cscale)
	
	local thumb = mw.html.create("div")
		:addClass("thumb")
		:addClass(align)
	local tinner = thumb:tag("div")
		:addClass("thumbinner")
		:css("width", width .. "px")
	local tcontext = tinner:tag("div")
		:attr("role", "img")
		:attr("aria-label", alt)
		:css("background", "#080")
		:css("width", width .. "px")
		:css("height", height .. "px")
		:css("overflow", "hidden")
		:wikitext(innerboard(args, pargs, width, height, cwidth, cheight, cscale)) -- Zawartość planszy
	local tcaption = tinner:tag("div")
		:addClass("thumbcaption")
		:wikitext(caption)
	
	return tostring(thumb)
end 

return p