Modul:Klasse/Work

Aus FürthWiki

Die Dokumentation für dieses Modul kann unter Modul:Klasse/Work/Doku erstellt werden

local p = {}

local com = require("Module:Common")
local str = require("Module:String")
local htm = require("Modul:HTML")
local atr = require("Module:Attribut")
local frm = require("Modul:Formular")
local fab = require("Modul:Faktenbox")

function p.Faktenbox(frame)														-- Das ist die Faktenbox der Klasse
	local args = frame:getParent().args
	local title = mw.title.getCurrentTitle().text
	local t = '<table class="wikitable">'..
	    '<th>[[FürthWiki:Semantik]]</th>'..
		'<th colspan="3">'..'[[KlassenName::'..title..']]</th>'

	t=t..'<tr>'..
	    '<td>[[Attribut:Bild|Bild dieser Klasse]]</td>'
	if not com.isEmpty(args.Bild) then
	    t=t..'<td colspan="3"><div class="ImageLink">[[Datei:'..
	    	args.Bild..'|48px]]</div></td>'
	    mw.smw.set{["Bild"] = "Datei:" .. args.Bild}
	end

	t=t..'</tr><tr>'..
	    '<td>[[Attribut:KlassenVorlage|Vorlage]]</td>'
	t=t..'<td colspan="3">[[KlassenVorlage::Vorlage:'..title..']]</td>'
	
	t=t..'</tr><tr>'..
	    '<td>[[Attribut:KlassenModul|Modul]]</td>'
	t=t..'<td colspan="3">[[KlassenModul::Modul:'..title..']]</td>'
	
	t=t..'</tr><tr>'..
	    '<td>[[Attribut:KlassenKategorie|Kategorie]]</td>'
	if not com.isEmpty(args.KlassenKategorie) then
	    t=t..'<td colspan="3">[[KlassenKategorie::Kategorie:'..args.KlassenKategorie..']]</td>'
	end
	
	t=t..'</tr><tr>'..
	    '<td>[[Attribut:KlassenFormular|Formular]]</td>'
	t=t..'<td colspan="3">[[KlassenFormular::Formular:'..title..']]</td>'
	
	t=t..'</tr><tr>'..
	    '<td>Attribut</td>'
	t=t..'<td colspan="3">[[Attribut:'..title..']]</td>'
	
	t=t..'</tr><tr>'..
	    '<td>[[Attribut:Suchformular|Suchformular]]</td>'
	if not com.isEmpty(args.KlassenKategorie) then
	    t=t..'<td colspan="2">[[Suchformular::Abfrage_'..args.KlassenKategorie..']]</td>'..
	    	'<td>[[Formular:Abfrage_'..args.KlassenKategorie..']]</td>'
	end
	
	t=t..'</tr><tr>'..
	    '<td>[[Attribut:Suchvorlage|Suchvorlage]]</td>'
	if not com.isEmpty(args.KlassenKategorie) then
	    t=t..'<td colspan="2">[[Suchvorlage::Abfrage_'..args.KlassenKategorie..']]</td>'..
	    	'<td>[[Spezial:Abfrage_ausführen/Abfrage_'..args.KlassenKategorie..']]</td>'
	end
	
	t=t..'</tr><tr>'..
	    '<td>[[Attribut:AttributListe|AttributListe]]</td>'
	if not com.isEmpty(args.AttributListe) then
	    t=t..'<td colspan="3">[[AttributListe::'..args.AttributListe..']]</td>'
	end
	
	t=t..'<tr>'..
		'<td>[[Bild:IconSearch.svg|16px|semantisches Browsen|link=Spezial:Durchsuchen/{{NAMESPACE}}:{{PAGENAME}}]]</td>'..
		'<td colspan="3">[[Spezial:Durchsuchen/{{NAMESPACE}}:{{PAGENAME}}|semantisches Browsen]]</td>'..
	'</tr>'
	t=t..'</table>'
	
	-- Attribut-Tabelle
	local attr_data = p.attrListParser(args.AttributListe)
	t = t .. "<table class=\"wikitable\">"
	t = t .. "<th colspan=" .. attr_data.width .. ">Attribut-Anordnung im Formular</th>"
	for _, outer in ipairs(attr_data.form_layout) do
		t = t .. "<tr>"
		if type(outer) ~= "table" then
			t = t .. "<td>[[Attribut:" .. outer .. "|" .. outer .. "]]</td>"
		else
			for _, inner in ipairs(outer) do
				t = t .. "<td>[[Attribut:" .. inner .. "|" .. inner .. "]]</td>"
			end
		end
		t = t .. "</tr>"
	end
	t = t .. "</table>"
	t = t .. "<b>Wird noch nicht unterstützt!</b>"

	if attr_data.width > 0 then
		table.sort(attr_data.list)												-- Liste wird umsortiert, macht aber nix
		attr = {"Attribut", "Datentyp", "EhemalsAttribut",
			"Anzeigegenauigkeit", "Einzahl", "Mehrzahl", "Delimiter",
			"FieldArgs", "Infotext", "Anzeigeformat"}
		-- Tabellen-Kopf
		t = t .. htm.tableHeader(attr)
		-- Tabellen-Zeilen
		for i, a in ipairs(attr_data.list) do
			local line = {}
			-- Attribut-Attribute
			local attr_val = atr.getAttrAttributes(a, title)
			attr_val = attr_val or {}
			-- Zeile befüllen
			for i, l in ipairs(attr) do
				if l == "Attribut" then
					line[i] = "[[Attribut:" .. a .. "|" .. a .. "]]"
				else
					line[i] = attr_val[l] or ""
				end
			end
			t = t .. htm.tableLine(line)
		end
		-- Tabellen-Fuß
		t = t .. htm.tableFooter()
	end

	-- Attribute-Liste in Attribut:Attribut ablegen
	for i = 1, #attr_data.list do
		attr_data.list[i] = "Attribut:" .. attr_data.list[i]					-- Liste wird umgebaut, macht aber nix
	end
	mw.smw.set{["Attribut"] = attr_data.list}
	
	return frame:preprocess(t)
end

function p.Formular(frame, klasse)												-- Das setzt das Formular einer Seite einer Klasse zusammen
	-- Kommandozeile zum Debuggen:
	-- frame=mw.getCurrentFrame(); print(p.Formular(frame, "Bauwerk"))
	local t = ""
	local attr_data = p.getAttrData(klasse)
	t = frm.attrForm(frame, attr_data)
	return t
end

function p.faktenboxDatenTab(fbdata, kindex)									-- Das setzt den DatenTab der Faktenbox einer Seite einer Klasse zusammen
--	mw.log("datenTab(fbdata)")
--	mw.logObject(frame, "frame")
	--[[ Konsolenzeile zum Debuggen:
	fab=require("Modul:Faktenbox"); fbdata=fab.getFbdata{pargs={Baujahr="1987",AktenNr="D-5-63-000-1464"}};
	fbdata.klasse={"Bauwerk"}; fbdata.kategorie={"Bauwerke"}; fbdata.fullpagename="Pegnitz"; fbdata.subpagename="Pegnitz";
	print(p.faktenboxDatenTab(fbdata)); mw.logObject(fbdata)
	]]
	local t = ""
	local klasse = fbdata.klasse[kindex or 1]
	local attr_data = p.getAttrData(klasse)
	-- Vorbereitung Test auf nicht-unterstützte Argumente
	local pargs_test = {}
	for a, _ in pairs(fbdata.pargs) do
		pargs_test[a] = true													-- nach Abarbeitung müssen alle nil sein
	end
	-- Zusammenbau
	t = t .. fab.zeileKategorieSeite(fbdata)
	-- EhemalsAttribut ermitteln (gibt es nur 1x)
	local ehemals_attribut
	for _, attr in ipairs(attr_data.list) do
		local attr_attr = attr_data.attr[attr]									-- Attribute des Attributs attr
		if attr_attr["EhemalsAttribut"] ~= nil then
			ehemals_attribut = attr_attr["EhemalsAttribut"]
			break
		end
	end
	-- Attribut-Zeilen
	for _, attr in ipairs(attr_data.list) do
		local attr_attr = attr_data.attr[attr]									-- Attribute des Attributs attr
		local delimiter = attr_attr["Delimiter"]
		local datentyp = attr_attr["Datentyp"]
		-- Sonderfälle unterscheiden und ggf. passende Faktenbox-Zeile einfügen
		if attr == "AktenNr" then												-- Sonderfall Denkmalschutz Akten-Nummer
			t = t .. fab.zeileAktenNr(fbdata)
		elseif attr == "TeilDesEnsembles" then									-- Sonderfall TeilDesEnsembles ("Ensemble " vorangestellt)
			t = t .. fab.zeileTeilDesEnsembles(fbdata)
		elseif attr_attr["EhemalsAttribut"] ~= nil then							-- Sonderfall Kombi von Ehemals-Attribut und Ende-Datum/Jahr
			if datentyp == "Seite" and											-- Seite und "jahr" am Ende bei Jahr
				string.find(attr, "jahr") == (#attr - 3) then
				t = t .. fab.zeileEndeJahr{fbdata = fbdata,						-- Z. B. Ehemals bei Abrissjahr
					attr_year = attr, attr_ended = attr_attr["EhemalsAttribut"],
					delimiter = delimiter}
			elseif datentyp == "Datum" then										-- Datum bei Datum
				-- to do: fab.zeileEndeDatum									-- Z. B. Verstorben bei Todesdatum
			end
		elseif datentyp == "Straße" then										-- Sonderfall Straße/Hausnummer
		elseif datentyp == "Straße2" then
		elseif datentyp == "Straße3" then
			-- to do
		elseif datentyp == "Datum" then											-- Sonderfall Datum
			t = t .. fab.zeileDatum{fbdata = fbdata, attr_date = attr}			-- setzt ebenso ...tag und ...jahr
		elseif attr ~= ehemals_attribut and attr ~= "Bild" then					-- ansonsten normale Zeile
			t = t .. fab.zeile{fbdata = fbdata, attr_name = attr,
				delimiter = delimiter}
		end
		pargs_test[attr] = nil													-- Argumente ausklammern
	end
	-- Rest der Tabelle
	t = fab.table_header_footer(t)
	t = t .. fab.zeileSemantikBrowsenAbfrage(fbdata)
	-- Tab draus machen
	t = fab.tab(t, "Daten")
	-- Nicht-unterstützte Argumente testen
	for _, a in ipairs(fab.karten_args) do										-- Karten-Argumente ausklammern
		pargs_test[a] = nil
	end
	local pargs_test_fail = false
	for _, _ in pairs(pargs_test) do											-- Argumente übrig?
		pargs_test_fail = true
		break
	end
	if pargs_test_fail then
		fab.addWartungsmeldung(fbdata, "Faktenbox-Daten nicht unterstützt (Einzelwerte)")
	end
--	mw.logObject(t, "t")
    return t
end

function p.getAttrData(klasse)
	-- Kommandozeile zum Debuggen:
	-- mw.logObject(p.getAttrData("Bauwerk"))
	local attr_data = initAttrData()
	-- AttributListe der Klasse abfragen
	local query = {"[[Klasse:" .. klasse .. "]]", "?AttributListe"}
	query = mw.smw.ask(query)
	if query ~= nil then
		local attr_list = query[1]["AttributListe"]
		-- AttributListe parsen, also Liste und Layout ermitteln
		attr_data = p.attrListParser(attr_list)
		-- Attribute der einzelnen Attribute hinzufügen
		for _, a in ipairs(attr_data.list) do
			attr_data.attr[a] = atr.getAttrAttributes(a, klasse)
		end
	end
	return attr_data
end

function p.attrListParser(attr_list, recursion)
	-- Kommandozeile zum Debuggen:
	-- mw.logObject(p.attrListParser(";A;{;B;C;};D;"))
	-- ergibt .form_layout = {A,{B,C},D} und .list = {A,B,C,D} und .width = 2
	local attr_data = initAttrData()
	local loop_count = 0
	attr_list = str.strip(attr_list or "")
	while loop_count < 100 and attr_list ~= "" do								-- Schleifenbegrenzung
		loop_count = loop_count + 1
		local semicolon = string.find(attr_list, ";")
		local brace_open = string.find(attr_list, "\{")
		local brace_close = string.find(attr_list, "\}")
		if (brace_open ~= nil and brace_close == nil) or						-- Klammer nicht paarweise
			(brace_open == nil and brace_close ~= nil) or						-- oder
			(brace_open or 0) >= (brace_close or 1) then						-- in falscher Reihenfolge
			attr_list = ""														-- => Abbruch
		elseif semicolon == nil and												-- letzer Eintrag
			brace_open == nil and brace_close == nil then
			table.insert(attr_data.form_layout, attr_list)
			table.insert(attr_data.list, attr_list)
			attr_list = ""
		elseif semicolon ~= nil and												-- Semikolon
			(brace_open == nil or semicolon < brace_open) then					-- ggf. vor öffnender Klammer
			local attr = str.strip(string.sub(attr_list, 1, semicolon - 1))
			if attr ~= "" then
				table.insert(attr_data.form_layout, attr)
				table.insert(attr_data.list, attr)
			end
			attr_list = string.sub(attr_list, semicolon + 1)
		elseif brace_open ~= nil and brace_close ~= nil and						-- eingebettete Klammerung (Zeile mit mehreren Attr.)
			brace_open < brace_close then
			if not recursion then												-- Rekursionsschutz, nur 2 Ebenen/Dimensionen bzw. 1 Selbstaufruf
				local attr_sublist =											-- Klammerinhalt
					string.sub(attr_list, brace_open + 1, brace_close - 1)
				attr_subdata = p.attrListParser(attr_sublist, true)				-- sich selbst aufrufen mit recursion = true
				if attr_subdata.width == 1 then
					table.insert(attr_data.form_layout, attr_subdata.list)
					for _, a in pairs(attr_subdata.list) do
						table.insert(attr_data.list, a)
					end
					attr_data.width = math.max(attr_data.width, #attr_subdata.list)
				end
			end
			attr_list = string.sub(attr_list, brace_close + 1)
		else																	-- da stimmt was nicht => Abbruch
			attr_list = ""
		end
		attr_list = str.strip(attr_list)
	end
	if #attr_data.list > 0 then													-- bei rein 1-dimensionaler Liste mind. 1 setzen
		attr_data.width = math.max(attr_data.width, 1)
	end
	return attr_data
end

function initAttrData()
	local attr_data = {
		form_layout = {},														-- 2D-Layout des Formulars
		list = {},																-- flache Liste der Attribute
		attr = {},																-- Attribute der Attribute
		width = 0}																-- Breite bei 2D-Layout, 1 bei 1-dimens.
	return attr_data
end

return p