Modul:Klasse: Unterschied zwischen den Versionen

Aus FürthWiki

(+ faktenboxDatenTab())
(Umbauten AttrData)
 
(9 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 3: Zeile 3:
local com = require("Module:Common")
local com = require("Module:Common")
local str = require("Module:String")
local str = require("Module:String")
local htm = require("Modul:HTML")
local atr = require("Module:Attribut")
local atr = require("Module:Attribut")
local frm = require("Modul:Formular")
local frm = require("Modul:Formular")
local fab = require("Modul:Faktenbox")
local fab = require("Modul:Faktenbox")


function p.Faktenbox( frame )
function p.Faktenbox(frame) -- Das ist die Faktenbox der Klasse
local args = frame:getParent().args
local args = frame:getParent().args
local t = p.daten( frame, args )
-- Use preprocess to render the factbox and all contens at once
return frame:preprocess(t)
end
function p.daten(frame, args)
local title = mw.title.getCurrentTitle().text
local title = mw.title.getCurrentTitle().text
local t = '<table class="wikitable">'..
local t = '<table class="wikitable">'..
Zeile 46: Zeile 40:
    '<td>[[Attribut:KlassenFormular|Formular]]</td>'
    '<td>[[Attribut:KlassenFormular|Formular]]</td>'
t=t..'<td colspan="3">[[KlassenFormular::Formular:'..title..']]</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>'..
t=t..'</tr><tr>'..
Zeile 72: Zeile 70:
'</tr>'
'</tr>'
t=t..'</table>'
t=t..'</table>'
return t
end
-- 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>"


function p.getAttrData(klasse)
if attr_data.width > 0 then
local attr_data = {}
table.sort(attr_data.list) -- Liste wird umsortiert, macht aber nix
local query = {"[[Klasse:" .. klasse .. "]]",
attr = {"Attribut", "Datentyp", "EhemalsAttribut",
"?AttributListe"}
"Anzeigegenauigkeit", "Einzahl", "Mehrzahl", "Delimiter",
query = mw.smw.ask(query)
"FieldArgs", "Infotext", "Anzeigeformat"}
if query ~= nil then
-- Tabellen-Kopf
local attributliste = query[1]["AttributListe"]
t = t .. htm.tableHeader(attr)
attributliste = str.splitAndStrip(attributliste, ";")
-- Tabellen-Zeilen
if #attributliste > 0 then
for i, a in ipairs(attr_data.list) do
attr_data = {}
local line = {}
for i, a in ipairs(attributliste) do
-- Attribut-Attribute
attr_data[i] = atr.getAttrAttributes(a, klasse)
local attr_val = atr.getAttrAttributes(a, title)
attr_data[i]["Attribut"] = a
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
end
t = t .. htm.tableLine(line)
end
end
-- Tabellen-Fuß
t = t .. htm.tableFooter()
end
end
return attr_data
 
-- 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
end


function p.Formular(frame, klasse)
function p.Formular(frame, klasse) -- Das setzt das Formular einer Seite einer Klasse zusammen
-- Kommandozeile zum Debuggen:
-- Kommandozeile zum Debuggen:
-- frame=mw.getCurrentFrame(); print(p.Formular(frame, "Bauwerk"))
-- frame=mw.getCurrentFrame(); print(p.Formular(frame, "Bauwerk"))
Zeile 103: Zeile 134:
end
end


function p.faktenboxDatenTab(fbdata, kindex)
function p.faktenboxDatenTab(fbdata, kindex) -- Das setzt den DatenTab der Faktenbox einer Seite einer Klasse zusammen
-- mw.log("datenTab(fbdata)")
-- mw.log("datenTab(fbdata)")
-- mw.logObject(frame, "frame")
-- mw.logObject(frame, "frame")
Zeile 109: Zeile 140:
fab=require("Modul:Faktenbox"); fbdata=fab.getFbdata{pargs={Baujahr="1987",AktenNr="D-5-63-000-1464"}};
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";
fbdata.klasse={"Bauwerk"}; fbdata.kategorie={"Bauwerke"}; fbdata.fullpagename="Pegnitz"; fbdata.subpagename="Pegnitz";
print(p.faktenboxDatenTab(fbdata))
print(p.faktenboxDatenTab(fbdata)); mw.logObject(fbdata)
]]
]]
local t = ""
local t = ""
local klasse = fbdata.klasse[kindex or 1]
local klasse = fbdata.klasse[kindex or 1]
local attr_data = p.getAttrData(klasse)
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
-- Zusammenbau
t = t .. fab.zeileKategorieSeite(fbdata)
t = t .. fab.zeileKategorieSeite(fbdata)
for _, a in ipairs(attr_data) do
-- EhemalsAttribut ermitteln (gibt es nur 1x)
local attr = a["Attribut"]
local ehemals_attribut
local delimiter = a["Delimiter"]
for _, attr in ipairs(attr_data.list) do
if a["Attribut"] == "AktenNr" then -- Denkmalschutz Akten-Nummer
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)
t = t .. fab.zeileAktenNr(fbdata)
elseif a["EhemalsAttribut"] ~= nil then -- Kombi von Ehemals-Attribut und Ende-Datum/Jahr
elseif attr == "TeilDesEnsembles" then -- Sonderfall TeilDesEnsembles ("Ensemble " vorangestellt)
t = t .. fab.zeileEndeJahr{fbdata = fbdata, -- Z. B. Ehemals bei Abrissjahr, Verstorben bei Todesdatum
t = t .. fab.zeileTeilDesEnsembles(fbdata)
attr_year = attr, attr_ended = a["EhemalsAttribut"], delimiter = delimiter}
elseif attr_attr["EhemalsAttribut"] ~= nil then -- Sonderfall Kombi von Ehemals-Attribut und Ende-Datum/Jahr
else
if datentyp == "Seite" and -- Seite und "jahr" am Ende bei Jahr
t = t .. fab.zeile{fbdata = fbdata, attr_name = attr, delimiter = delimiter}
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
-- to do
elseif attr ~= ehemals_attribut and attr ~= "Bild" then -- ansonsten normale Zeile
t = t .. fab.zeile{fbdata = fbdata, attr_name = attr,
delimiter = delimiter}
end
end
pargs_test[attr] = nil -- Argumente ausklammern
end
end
-- Rest der Tabelle
t = fab.table_header_footer(t)
t = fab.table_header_footer(t)
t = t .. fab.zeileSemantikBrowsenAbfrage(fbdata)
t = t .. fab.zeileSemantikBrowsenAbfrage(fbdata)
-- Tab draus machen
-- Tab draus machen
t = fab.tab(t, "Daten")
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")
-- mw.logObject(t, "t")
     return 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
end


return p
return p

Aktuelle Version vom 6. März 2026, 18:27 Uhr

Seiten-Übersicht

Zur Klasse Klasse gehörende Seiten:
Hauptseite Unterseiten
Allgemein
Faktenbox Vorlagen
Formulare
Module
Abfrage Vorlagen


Formulare


Sonstige


Faktenbox()

Die Faktenbox der Klassen.

Formular()

Baut das Formular einer Artikelseite (Lemma) einer Klasse zusammen. Als Basis wird dafür die in der jeweiligen Klasse eingetragene Attribut:AttributListe genommen, daraus die Attribut-Datentabelle attr_data generiert und diese weiter an attrForm() im Modul:Formular übergeben.

faktenboxDatenTab()

Baut den Daten-Tab der Faktenbox einer Artikelseite (Lemma) einer Klasse zusammen. Als Basis wird dafür die in der jeweiligen Klasse eingetragene Attribut:AttributListe genommen, daraus die Attribut-Datentabelle attr_data generiert und dann zeilenweise in Reihenfolge der AttributListe abgearbeitet.

Dabei werden die verschiedenen Sonderfälle der Faktenbox-Zeilen beachtet (z. B. Denkmalschutz-Aktennummer, Datum, Ehemals, ...). Siehe Modul:Faktenbox/Zeilen.

getAttrData()

Gibt Attribut-Datentabelle attr_data zurück.

attrListParser()

Analysiert übergebene Attribut:AttributListe und gibt von Attribut-Datentabelle attr_data die Werte attr_data.form_layout, attr_data.width und attr_data.list zurück.

Attribut-Datentabelle attr_data


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
			-- to do
		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