Interested Article - GroupMembers

Документация
local p = {}

local mapping = {
	name = 'имя',
	from = 'начало',
	to = 'конец',
	instruments = 'инструменты',
	album = 'альбом'
}

local collors_list = {
	'red',
	'green',
	'blue',
	'orange',
	'pink',
	'drabgreen',
	'claret',
	'darkblue',
	'purple',
	'drabgreen',
}

local collectData = function( args )
	local albums = {}
	local colors = {}
	local members = {}

	local instruments = {}

	for key, value in pairs( args ) do
		local param, pos = string.match( key, '^(.+)(%d+)$' )
		pos = tonumber( pos )
		
		if param == mapping.album then
			albums[ pos ] = {
				date = value
			}
		else
			for map_key, map_param in pairs( mapping ) do
				if param == map_param then
					if not members[ pos ] then
						members[ pos ] = {}
					end
					members[ pos ][ map_key ] = value
					
					if map_key == 'instruments' then
						if not instruments[ value ] then
							local color_pos = next( collors_list )
							instruments[ value ] = collors_list[ color_pos ]

							table.insert( colors, {
								id = collors_list[ color_pos ],
								value = collors_list[ color_pos ],
								legend = value,
							} )

							table.remove( collors_list, color_pos )
						end
						members[ pos ].color = instruments[ value ]
					end

					break
				end
			end
		end
	end

	if #albums then
		table.insert( colors, {
			id = 'studio',
			value = 'black',
			legend = 'Студийный альбом',
		} )
	end

    return {
    	from = args[ mapping.from ],
    	to = args[ mapping.to ] or os.date( '%Y-%m-%d' ),
    	colors = colors,
    	albums = albums,
    	members = members
    }
end

local timelineDate = function( isoDate )
	local dateParts = mw.text.split( isoDate, '-', true )
	return dateParts[ 3 ] .. '/' .. dateParts[ 2 ] .. '/' .. dateParts[ 1 ]
end

local renderTimeline = function( params, frame )
	local content = [[
ImageSize = width:800 height:auto barincrement:25
PlotArea = left:110 bottom:80 top:10 right:10
Alignbars = justify
DateFormat = dd/mm/yyyy
TimeAxis = orientation:horizontal format:yyyy
Legend = orientation:vertical position:bottom columns:3
]]

	content = content .. 'Period = from:' .. timelineDate( params.from ) .. ' till:' .. timelineDate( params.to ) .. '\n'

	local fromYear = tonumber( mw.text.split( params.from, '-', true )[ 1 ] ) + 1
	content = content .. 'ScaleMajor = increment:3 start:' .. fromYear .. '\n'
	content = content .. 'ScaleMinor = increment:1 start:' .. fromYear .. '\n'

	content = content .. 'Colors =\n'
	for _, color in ipairs( params.colors ) do
		content = content .. ' id:' .. color.id ..
			' value:' .. color.value ..
			' legend:' .. string.gsub( color.legend, ' ', '_' ) ..
			'\n'
	end

	content = content .. 'LineData =\n layer:back\n color:studio\n'
	for _, album in ipairs( params.albums ) do
		content = content .. ' at:' .. timelineDate( album.date ) .. '\n'
	end

	local barData = 'BarData =\n'
	local plotData = 'PlotData =\n'
	for _, member in ipairs( params.members ) do
		local hash = mw.hash.hashValue( 'md5', member.name )
		barData = barData .. ' bar:' .. hash ..
			' text:"' .. member.name .. '"' ..
			'\n'
		plotData = plotData .. ' bar:' .. hash ..
			' from:' .. timelineDate( member.from ) ..
			' till:' .. timelineDate( member.to or params.to ) ..
			' color:' .. member.color ..
			' width:10' ..
			'\n'
	end
	content = content .. barData .. plotData .. '\n'

	return frame:extensionTag( 'timeline', content )
end

p.render = function( frame )
	local params = collectData( frame:getParent().args )
	return renderTimeline( params, frame )
end

return p
Источник —

Same as GroupMembers