Module:Lunar eclipse

From blackwiki
Jump to navigation Jump to search
local eclipse = {}
local args = {}

local data_module_prefix = "Module:Lunar eclipse/db/"

local function ifnotempty(s,a,b)
	if (s and s ~= '') then
		return a
	else
		return b
	end
end

local function ifexist(page)
    if not page then return false end
    if mw.title.new(page).exists then return true end
    return false
end

local function parsedate(y,m,d,fmt)
	local lang = mw.language.getContentLanguage()
	d = (tonumber(d) < 10) and ('0' .. tonumber(d)) or (d)
	m = (tonumber(m) < 10) and ('0' .. tonumber(m)) or (m)
	local success, result = pcall(lang.formatDate, lang, fmt, y .. '-' .. m .. '-' .. d)
	return success and result or nil
end

local function parsecoord(frame, s)
	local lat = s:match('^%s*([%d][%d.]*)%s*[NS]%s*[%d][%d.]*[EW]%s*$')
	local  NS = s:match('^%s*[%d][%d.]*%s*([NS])%s*[%d][%d.]*[EW]%s*$')
	local lon = s:match('^%s*[%d][%d.]*%s*[NS]%s*([%d][%d.]*)[EW]%s*$')
	local  EW = s:match('^%s*[%d][%d.]*%s*[NS]%s*[%d][%d.]*([EW])%s*$')
	if( lat and NS and lon and EW ) then
		return frame:expandTemplate{ title = 'coord', args = {lat, NS, lon, EW, 'type:landmark'} }
	else
		return s
	end
end

local function parsetime(s)
	if(s and s ~= '') then
		local hr, mn, sc = nil, nil, nil
		local hr = s:match('^%s*([%d][%d]*):%s*[%d][%d]*s:%s*[%d][%d]*%s*$')
		if hr then
			mn = s:match('^%s*[%d][%d]*:%s*([%d][%d]*)s:%s*[%d][%d]*%s*$')
			sc = s:match('^%s*[%d][%d]*:%s*[%d][%d]*s:%s*([%d][%d]*)%s*$')
			return hr .. '&nbsp;h ' .. mn .. '&nbsp;m ' .. sc .. '&nbsp;s'
		end
		mn = s:match('^%s*([%d][%d]*)s:%s*[%d][%d]*%s*$')
		if mn then
			sc = s:match('^%s*[%d][%d]*s:%s*([%d][%d]*)%s*$')
			return mn .. '&nbsp;m ' .. sc .. '&nbsp;s'
		end
		sc = s:match('^%s*([%d][%d]*)%s*$')
		if sc then
			return sc .. '&nbsp;s'
		end
	end
	return s
end

local function parsetype(s)
	if s == 'T' then
		return 'Total'
	elseif s == 'P' then
		return 'Partial'
	elseif s == 'N' then
		return 'Penumbral'
	elseif s == 'D' then
		return 'Descending'
	elseif s == 'A' then
		return 'Ascending'
	else
		return s
	end
end

local function cataloglink(t, y, m, d, l)
	if t then
		local y1 = tostring(math.floor( (tonumber(y) - 1) / 50 ) * 50 + 1)
		return '[https://eclipse.gsfc.nasa.gov/LEplot/LEplot' .. y1 .. '/LE' 
			.. parsedate(y,m,d,'YMj') .. t .. '.pdf ' 
			.. (l or 'eclipse.gsfc.nasa.gov') .. ']'
	else
		return ''
	end
end

local function loadlunardb(frame, s)
	local yearstr = s:match('^%s*([%d][%d][%d][%d])[A-Z][a-z][a-z][%d][%d]%s*$') or ''
	local function setarg(k, v)
		if(v and v ~= '') then args[k] = v end
	end
	if( yearstr ~= '' ) then
		local dbsubpage = math.floor( (tonumber(yearstr) - 1) / 50 ) * 5
		local dbpage  = data_module_prefix .. tostring( dbsubpage )
		if (ifexist(dbpage)) then
			local data = mw.loadData(dbpage)
			local dargs = data[s]
			setarg('date', parsedate(dargs['y'], dargs['m'] or dargs['m3'] or dargs['m2'], dargs['d'] or dargs['d2'], 'F j, Y'))
			setarg('image', (dargs['imphoto'] and dargs['imphoto'] ~= '') and '[[File:' .. dargs['imphoto']  .. '|240px]]' or nil)
			setarg('caption', dargs['capphoto'])
			setarg('image1', (dargs['imclose'] and dargs['imclose'] ~= '') and '[[File:' .. dargs['imclose']  .. '|240px]]' or nil)
			setarg('caption1', dargs['capclose'])
			setarg('image2', (dargs['imwide'] and dargs['imwide'] ~= '') and '[[File:' .. dargs['imwide']  .. '|240px]]' or nil)
			setarg('caption2', dargs['capwide'])
			setarg('chart', (dargs['imchart'] and dargs['imchart'] ~= '') and '[[File:' .. dargs['imchart']  .. '|240px]]' or nil)
			setarg('chart_caption', dargs['capchart'])
			setarg('type_ref', '')
			setarg('nature', parsetype(dargs['Ty'] or ''))
			setarg('node', parsetype(dargs['Node'] or ''))
			setarg('gamma', dargs['Gam'])
			setarg('magnitude', dargs['Mag'])
			setarg('saros', dargs['Saros'] and '[[Lunar Saros ' .. dargs['Saros'] .. '|'  .. dargs['Saros'] .. ']]')
			setarg('saros_sequence', dargs['Mem'])
			setarg('saros_total', dargs['Max'])
			setarg('max_eclipse_ref', '')
			setarg('tot_duration', parsetime(dargs['Dt']))
			setarg('par_duration', parsetime(dargs['Dp']))
			setarg('pen_duration', parsetime(dargs['Dn']))
			setarg('times_ref', '')
			setarg('time', dargs['time'])
			setarg('p1', dargs['p1'])
			setarg('p4', dargs['p2'] or dargs['p4'])
			setarg('u1', dargs['u1'])
			setarg('u2', dargs['u2'])
			setarg('u3', dargs['u3'])
			setarg('u4', dargs['u4'])
			setarg('cat', cataloglink(dargs['Ty'], dargs['y'], dargs['m'] or dargs['m3'] or dargs['m2'], dargs['d'] or dargs['d2'], l) )
		end
	end
end

local function infobox(frame)
	local abovestr = ifnotempty(args['date'], 
		"Lunar eclipse of ''" .. (args['date'] or '') .. "''",
		"For instructions on use, see [[Template:Infobox lunar eclipse]]")
	local bgcolor = args['background'] or args['bgcolour'] or ''
	local chartstr = ifnotempty(args['chart'],
		"<div style='padding-bottom:0.5em;'>" .. 
		(args['chart'] or '') .. ifnotempty(args['chart_caption'], 
			"<div style='line-height:1.2em; padding-top:0.1em;'>" ..
			(args['chart_caption'] or 'Eclipse chart') .. "</div>", '') .. '</div>')

	return frame:expandTemplate{ title = 'infobox', args = {
		["bodyclass"] = "vevent",
		["bodystyle"] = "width:25em; text-align:left; font-size:90%;",
		["above"] = abovestr,
		["aboveclass"] = "summary",
		["abovestyle"] = "padding-bottom:0.25em; background:" .. bgcolor .. "; line-height:1.2em; text-align:center; font-size:115%;",
------------------ Images and maps ------------------
		["image"] = args['image'] or '',
		["caption"] = args['caption'] or '',
		["image1"] = args['image1'] or '',
		["caption1"] = args['caption1'] or '',
		["image2"] = args['image2'] or '',
		["caption2"] = args['caption2'] or '',
		["imagestyle"] = "padding-bottom:0.5em;",
		["captionstyle"] = "padding-top:0.1em; line-height:1.2em;",
		["headerstyle"] = "background:#eee; font-size:105%;",
		["labelstyle"] = "padding:0 0.5em 0 0; line-height:1.1em;",
		["datastyle"] = "padding:0; line-height:1.2em; vertical-align:middle;",
		["data1"] = chartstr,
------------- Type of eclipse -------------
		["header2"] = "Type of eclipse" .. (args['type_ref'] or ''),
		["label3"]  = "[[Lunar eclipse#Types of lunar eclipse|Type]]",
		["data3"]   = args['nature'] or '',
		["label4"]  = "[[Gamma (eclipse)|Gamma]]",
		["data4"]   = args['gamma'] or '',
		["label5"]  = "[[Magnitude of eclipse|Magnitude]]",
		["data5"]   = args['magnitude'] or '',
------------------ Durations (minutes) ------------------
		["header7"] = "Maximum eclipse" .. (args['max_eclipse_ref'] or ''),
		["label8"] = "Totality",
		["data8"] = args['tot_duration'] or '',
		["label9"] = "Partiality",
		["data9"] = args['par_duration'] or '',
		["label10"] = "Penumbral",
		["data10"] = args['pen_duration'] or '',
----------------------- Times -----------------------
		["header12"] = "Times ([[UTC]])" .. (args['times_ref'] or ''),
		["label13"] = "(P1) Penumbral begin",
		["data13"] = args['p1'] or '',
		["label14"] = "(U1) Partiality begin",
		["data14"] = aargs['u1'] or '',
		["label15"] = "(U2) Totality begin",
		["data15"] = args['u2'] or '',
		["label16"] = "Greatest eclipse",
		["data16"] = args['time'] or '',
		["label17"] = "(U3) Totality end",
		["data17"] = args['u3'] or '',
		["label18"] = "(U4) Partiality end",
		["data18"] = args['u4'] or '',
		["label19"] = "(P4) Penumbral end",
		["data19"] = args['p4'] or '',
------------------------ Event references -------------------------
		["header20"] = "References",
		["label21"] = "[[Saros cycle]]",
		["data21"] = (args['saros'] or '') 
			.. " (" .. (args['saros_sequence'] or '') .. " of " .. (args['saros_total'] or '') .. ")",
		["label22"] = "Catalog",
		["data22"] = args['cat'] or '',
		} }
	
end

function eclipse.box(frame)
	args = require('Module:Arguments').getArgs(frame, {
			wrappers = 'Template:Infobox lunar eclipse'
		})

	if( args['2'] and args['2'] ~= '') then
		loadlunardb(frame,args['2'])
	elseif( args['1'] and args['1'] ~= '') then
		loadlunardb(frame,args['1'])
	end
	
	return infobox(frame)
end

return eclipse