local function GetBracketData(fullname)
fullname = string.gsub(fullname,'"','');
local num = tonumber(string.sub(fullname,1,6)) or 0;
local posbrackl = string.find(fullname,'(',1,true) or false;
local posbrackr = string.find(fullname,')',1,true) or false;
if posbrackl and posbrackr then
return string.sub(fullname,posbrackl+1,posbrackr-1), true;
else
return '', false;
end
end
--Aufteilen einer einzelnen Zeile anhand eines Separators.
local function CutString(str,sp)
local tbl = {};
local text = str;
local teil;
sep = sp or "/";
if #str == 0 then
return tbl;
end
text = text ..sep
for i = 1,50 do
pos = string.find(text,sep) or 0;
teil = string.sub(text,1,pos-1);
if pos < 1 then
break;
end
table.insert (tbl,teil);
text = string.sub(text,pos+1);
end
return tbl;
end
-- Teilen einer Zeichenkette an enthaltenen Zeilenumbrüchen
local function GetLines(str)
return CutString(str,'\n')
end
-- GetDataPage liest den Quelltext einer Datenseite aus und gibt die Zeilen im Pre-Tag in einer table zurück.
function GetDataPage(namespace,title)
local Seite = mw.title.makeTitle(namespace, title);
local Content = Seite:getContent()
local Lines = {};
local von;
local bis;
-- alles außerhalb des Pre-Tags entfernen
von = string.find(Content,'<pre>',1,true) or false;
bis = string.find(Content,'</pre>',1,true) or false;
if von and bis then
Content = string.sub(Content,von,bis+5);
else
Content = nil;
return Lines, false;
end
Lines = GetLines(Content);
Content = nil;
return Lines, true;
end
function GetDataSet(Id)
local Zeilen = {};
local Fields ={};
local Set = {};
local Cells = {};
local Zahl = 0;
local SPK = 2000000 + Id;
local isOK;
Zeilen, isOk = GetDataPage('Vorlage','Infobox Asteroid/Daten')
if not isOk then
return Cells, Fields, false
end
table.remove (Zeilen , 1); -- Pre-Tag entfernen
Fields = CutString(Zeilen[1],',');
for row = 2, #Zeilen do
Set = CutString(Zeilen[row],',')
for col = 1, #Fields do
Cells[Fields[col]] = Set[col];
end
Zahl = tonumber(Cells['spkid']) or 0;
if Zahl == SPK then
Zeilen = nil;
return Cells, Fields, true;
end
end
return Cells, Fields, false;
end
function GetOrbitPeriodString(days) -- Ausgabestring für die Umlaufdauer
local PeriodDay = tonumber(days) or 0;
local PeriodYear = PeriodDay / 365.25;
local years = 0;
local days = 0;
if PeriodYear >= 100 then
years = math.floor(PeriodYear + 0.5);
days = false;
elseif PeriodYear >= 1 then
years = math.floor(PeriodDay / 365.25);
days = math.floor((PeriodDay - years *365.25) + 0.5);
if days > 364 then -- wegen Rundung möglich
years = years + 1;
days = days -365;
end
else
years = false;
days =math.floor(PeriodDay + 0.5);
end
local Periode = '';
if years then
Periode = Periode .. tostring(years) .. ' [[Jahr|a]] '
end
if days then
Periode = Periode .. tostring(days) .. ' [[Tag|d]]'
end
return Periode;
end
function GetRotationString(hours) -- Ausgabestring für die Rotation
local Tage = 0;
local Std = 0;
local Min = 0
local Sek = 0;
local RotStr='';
local Rotation= tonumber(hours) or 0;
Rotation = math.floor(Rotation * 3600 + 0.5); -- in ganze Sekunden umwandeln
-- hier liegt die Rotation in Sekunden vor.
if Rotation >= 8638200 then -- >= 99 Tage und 23,5 Stunden; Ausgabe nur ganze Tage
Tage = math.floor(Rotation/86400 + 0.5);
RotStr = tostring(Tage) .. ' [[Tag|d]] ';
elseif Rotation >= 86400 then -- 1 Tag bis < 99 Tage 23,5 Stunden, Ausgabe Tage und Stunden
Tage = math.floor(Rotation/86400);
Std = math.floor((Rotation - Tage * 86400)/3600 + 0.5);
if Std == 24 then
Tage = Tage + 1;
Std = 0;
end
RotStr = tostring(Tage) .. ' [[Tag|d]] ' .. tostring(Std) .. ' [[Stunde|h]] ';
elseif Rotation >= 3600 then -- Eine Stunde bis < 1 Tag, Ausgabe Stunden und Minuten
Rotation = math.floor(Rotation / 60 + 0.5);
-- Rotation in diesem case in Minuten, gerundet auf ganze Zahl
Std = math.floor(Rotation /60);
Min = Rotation % 60;
RotStr = tostring(Std) .. ' [[Stunde|h]] ' .. tostring(Min) .. ' [[Minute|min]] ';
elseif Rotation > 0 then -- unter einer Stunde, aber > Null
Min = math.floor(Rotation /60);
Sek = Rotation % 60;
RotStr = RotStr .. tostring(Min) .. ' [[Minute|min]] ';
RotStr = RotStr .. tostring(Sek) .. ' [[Sekunde|s]]';
else -- Wert nicht positiv
RotStr = ''
end
return RotStr;
end
local p = {}
-- Aufruf der Infobox mit eingelesenen Werten
function p.CreateTemplate(frame)
local ID = frame.args['SSD_ID'] or 0;
if ID == 0 then
return '<div class="error float-right">Es wurde keine gültige ID angegeben!</div>';
end
local Felder = {};
local Werte = {};
local isOk = false;
Werte, Felder, isOk = GetDataSet(ID);
if not isOk then
return '<div class="error float-right">Es wurde kein gültiger Datensatz gefunden!</div>';
end
local a = tonumber(Werte['a'] or '') or -1;
local e = tonumber(Werte['e'] or '') or -1;
local i = tonumber(Werte['i'] or '') or -1;
local Perihel = a * (1 - e);
local Aphel = a * (1 + e);
local TNO = ''; if a > 30 then TNO = 'ja'; end
local Smass = Werte['spec_B'] or '';
Smass=mw.ustring.gsub(Smass, '"','');
local Tholen = Werte['spec_T'] or '';
Tholen=mw.ustring.gsub(Tholen, '"','');
local Albedo = Werte['albedo'] or '';
local H = Werte['H'] or '';
local Knoten = tonumber(Werte['om'] or '') or '';
local Periwinkel = tonumber(Werte['w'] or '') or '';
local PeriJD = tonumber(Werte['tp'] or '') or '';
local Epoche = tonumber(Werte['epoch'] or '') or '';
local Durchmesser = tonumber(Werte['diameter'] or '') or 0;
local Abmessungen = Werte['extent'] or '';
Abmessungen = mw.ustring.gsub( Abmessungen, 'x',' × ');
Abmessungen = mw.ustring.gsub( Abmessungen, '"','');
local Rotation = tonumber(Werte['rot_per']) or 0;
local Tage = 0;
local Std = 0;
local Min = 0
local Sek = 0;
local RotStr='';
if Rotation > 0 then
Rotation= math.floor(Rotation * 3600 + 0.5); -- in ganze Sekunden umwandeln
Tage = math.floor(Rotation/86400);
Std = math.floor((Rotation - Tage * 86400)/3600);
Min = math.floor((Rotation - Tage * 86400 - Std * 3600) /60);
Sek = Rotation % 60;
if Tage > 0 then
RotStr = tostring(Tage) .. ' [[Tag|d]] ';
end
if Tage < 100 then
RotStr = RotStr .. tostring(Std) .. ' [[Stunde|h]] ';
end
if Tage < 10 then
RotStr = RotStr .. tostring(Min) .. ' [[Stunde|min]] ';
end
if Tage == 0 then
RotStr = RotStr .. tostring(Sek) .. ' [[Sekunde|s]]';
end
end
local Dichte = '';
local Masse = '';
local GM = tonumber(Werte['GM'] or '') or 0;
Masse = GM / 6.67430 * math.pow(10,20);
if Durchmesser > 0 and Masse > 0 then
Dichte = Masse / ( math.pow(10,12)* Durchmesser * Durchmesser * Durchmesser * 3.1415926538 /6 )
Dichte = string.format('%5.3f',Dichte);
else
Dichte = '';
end
if Masse == 0 then
Massetext = '';
else
Masse = string.format('%7.5E',Masse);
local pos = string.find(Masse,"E") or 0
if pos > 0 then
Massetext = string.sub(Masse,pos-1) .. ' · 10<sup>' .. string.sub(Masse,pos+1) .. '</sup>'
else
Massetext = '';
end
end
local Name = Werte['name'] or '';
local SysName = GetBracketData(Werte['full_name'] or '')
-- unbenannte Asteroiden bekommen den syst. Namen
if Name =='' then
Name = SysName;
SysName = ''
end
local PeriodDay = tonumber(Werte['per'] or 0)
local PeriodYear = PeriodDay / 365.25;
local years = 0;
local days = 0;
if PeriodYear >= 100 then
years = math.floor(PeriodYear + 0.5);
days = false;
elseif PeriodYear >= 1 then
years = math.floor(PeriodDay / 365.25);
days = math.floor((PeriodDay - years *365.25) + 0.5);
if days > 364 then
years = years + 1;
days = days -365;
end
else
years = false;
days =math.floor(PeriodDay + 0.5);
end
local Umlaufdauer = '';
if years then
Umlaufdauer = Umlaufdauer .. tostring(years) .. ' a '
end
if days then
Umlaufdauer = Umlaufdauer .. tostring(days) .. ' d'
end
-- Es fehlt noch die Umrechnung für Bahngeschwindigkeit
local Args = frame.args; -- Vorbelegung von Args mit den übergebenen Werten
-- einige nicht angegebene Parameter werden durch die ausgelesenen ersetzt:
if Args['Name'] == '' then Args['Name'] = Name; end
if Args['anderer_Name'] == '' then Args['anderer_Name'] = SysName; end
Args['Tholen'] = Tholen;
Args['TholenRef']=''
Args['Smass'] = Smass;
Args['SmassRef']=''
if a > 0 then
Args['Große_Halbachse'] = string.format('%9.4f',a);
else
Args['Große_Halbachse'] = '';
end
if e >= 0 then
Args['Exzentrizität'] = string.format('%6.4f',e);
else
Args['Exzentrizität'] = '';
end
if i >= 0 then
Args['Bahnneigung'] = string.format('%7.2f',i);
else
Args['Bahnneigung'] = '';
end
if a > 0 and e >= 0 then
Args['Perihel'] = string.format('%.3f',Perihel);
Args['Aphel'] = string.format('%.3f',Aphel);
else
Args['Perihel'] = '';
Args['Aphel'] = '';
end
if Knoten ~='' then
Args['Knoten'] = string.format('%7.2f',Knoten);
else
Args['Knoten'] = '';
end
if Periwinkel ~='' then
Args['Periwinkel'] = string.format('%7.2f',Periwinkel);
else
Args['Periwinkel'] = '';
end
if Epoche ~='' then
Args['Epoche'] = string.format('%10.1f',Epoche);
else
Args['Epoche'] = '';
end
if PeriJD ~='' then
Args['PeriJD'] = string.format('%10.1f',PeriJD);
else
Args['PeriJD'] = '';
end
Args['Rotationsperiode'] = Rotation;
Args['Masse'] = Massetext;
Args['Dichte'] = Dichte;
Args['Albedo'] = Albedo;
if H ~='' then
Args['Absolute_Helligkeit'] = string.format('%8.3f',H);
else
Args['Absolute_Helligkeit'] = '';
end
Args['Abmessungen'] = Abmessungen;
Args['Umlaufdauer'] = Umlaufdauer;
Args['Rotationsperiode'] = RotStr;
Args['Umlaufgeschwindigkeit'] = '';
Args['SSD_TNO'] = TNO ;
if frame.args['test'] or '' ~= '' then
local S = tostring(#Args) ..'\n';
S = S .. '\n* SSD_ID = ' ..tostring(Args['SSD_ID'] or 'nil')
S = S .. '\n* SSD_TNO = ' ..tostring(Args['SSD_TNO'] or 'nil')
S = S .. '\n* Name = ' ..tostring(Args['Name'] or 'nil')
S = S .. '\n* anderer_Name = ' ..tostring(Args['anderer_Name'] or 'nil')
S = S .. '\n* Tholen = ' ..tostring(Args['Tholen'] or 'nil')
S = S .. '\n* Smass = ' ..tostring(Args['Smass'] or 'nil')
S = S .. '\n* Große_Halbachse = ' ..tostring(Args['Große_Halbachse'] or 'nil')
S = S .. '\n* Exzentrizität = ' ..tostring(Args['Exzentrizität'] or 'nil')
S = S .. '\n* Bahnneigung = ' ..tostring(Args['Bahnneigung'] or 'nil')
S = S .. '\n* Perihel = ' ..tostring(Args['Perihel'] or 'nil')
S = S .. '\n* Aphel = ' ..tostring(Args['Aphel'] or 'nil')
S = S .. '\n* Knoten = ' ..tostring(Args['Knoten'] or 'nil')
S = S .. '\n* Periwinkel = ' ..tostring(Args['Periwinkel'] or 'nil')
S = S .. '\n* Epoche = ' ..tostring(Args['Epoche'] or 'nil')
S = S .. '\n* PeriJD = ' ..tostring(Args['PeriJD'] or 'nil')
S = S .. '\n* Rotationsperiode = ' ..tostring(Args['Rotationsperiode'] or 'nil')
S = S .. '\n* Masse = ' ..tostring(Args['Masse'] or 'nil')
S = S .. '\n* Dichte = ' ..tostring(Args['Dichte'] or 'nil')
S = S .. '\n* Albedo = ' ..tostring(Args['Albedo'] or 'nil')
S = S .. '\n* Absolute_Helligkeit = ' ..tostring(Args['Absolute_Helligkeit'] or 'nil')
S = S .. '\n* Abmessungen = ' ..tostring(Args['Abmessungen'] or 'nil')
S = S .. '\n* Umlaufdauer = ' ..tostring(Args['Umlaufdauer'] or 'nil')
S = S .. '\n* Umlaufgeschwindigkeit = ' ..tostring(Args['Umlaufgeschwindigkeit'] or 'nil')
return S;
end
local Text = frame:expandTemplate{ title = 'Vorlage:Infobox Asteroid/Extrabox', args = Args }
return Text;
end
function p.CheckData(frame)
local Seite = mw.title.makeTitle('Vorlage','Infobox Asteroid/Daten');
local Content = Seite:getContent()
local c;
local von;
local bis;
-- alles außerhalb des Pre-Tags entfernen
von,c = string.find(Content,'<pre>',1,true);
c, bis = string.find(Content,'</pre>',1,true);
Content = string.sub(Content,von,bis);
return string.sub(Content,1, frame.args[1]);
end
function p.OrbitPeriod(frame)
local Tage = tonumber(frame.args[1]) or -1;
local Text = "";
if Tage >= 0 then
Text = GetOrbitPeriodString(Tage);
else
Text = frame.args[1]; -- wenn keine Zahl, dann unverändert zurück
end
return Text;
end
function p.Rotation(frame)
local Stunden = tonumber(frame.args[1]) or 0;
local Text = "";
if Stunden > 0 then
Text = GetRotationString(Stunden)
else
Text = frame.args[1]; -- wenn keine Zahl, dann unverändert zurück
end
return Text;
end
return p
--[[
Auftrag: In einem tabellarischen Seiteninhalt eine Zeile suchen und die
Werte der Spalten in eine Wiki-Schablone einfügen.
Bedeutung der Spalten in der ersten Zeile
]]