Module:Mermaid

From mcr
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Documentation for this module may be created at Module:Mermaid/doc

local p = {}

function p.wrap( s, length )
	s = mw.text.trim( s )
	local oldindex = 1
	local index = string.find( s, ' ' )
	while ( index ) do
		if ( index - oldindex >= length ) then
			local temp = string.sub( s, 1, index - 1 ) .. '<BR/>' .. string.sub( s, index + 1 )
			s = temp
			oldindex = index + 4
		end
		index = string.find( s, ' ', index + 1)
	end
	return s
end

function p.cleanseDisplayTitle( displaytitle, extra )
	local s = displaytitle
	s = string.gsub( s, '"', '' )
	s = string.gsub( s, '%[', '' )
	s = string.gsub( s, '%]', '' )
	s = string.gsub( s, '&', 'and' )
	s = p.wrap ( s, 15 )
	return s .. extra
end

function p.getNodes( category, depends_on_property, status_property,
	owner_property, project_property, column_property, tag_property, filter,
	unlimited )
	local nodes = {}
	local result = mw.smw.getQueryResult( '[[Category:' .. category .. ']]' ..
		filter .. '|?' .. depends_on_property .. '|?' .. status_property ..
		'|?' .. owner_property .. '|?' .. project_property .. '|?' ..
		column_property .. '|?' .. tag_property .. '|limit=500' )
	if result ~= nil then
		for k1,v1 in pairs( result.results ) do
			local column = v1.printouts[column_property][1]
			local status = v1.printouts[status_property][1]
			if unlimited or ( column ~= 'Watching' and ( status == 'open' or status == 'stalled' ) ) then
				nodes[v1.fulltext] = {}
				local extra = ''
				local owner = table.concat( v1.printouts[owner_property], ', ' )
				if ( #owner > 0 ) then
					extra = '<BR/>' .. owner
				end
				if v1.printouts[column_property][1] ~= nil then
					for k2,v2 in pairs ( v1.printouts[project_property] ) do
						if string.match( v2, '^Core Platform Team Kanban' ) or
							string.match( v2, '^Core Platform Team Backlog' ) then
							extra = extra .. '<BR/>' .. v2 .. ' (' ..
								v1.printouts[column_property][1] .. ')'
							break
						end
					end
				end
				nodes[v1.fulltext].fullurl = v1.fullurl
				nodes[v1.fulltext].displaytitle =
					p.cleanseDisplayTitle( v1.displaytitle, extra )
					nodes[v1.fulltext].status = status
				nodes[v1.fulltext].dependencies = {} 
				for k2,v2 in pairs ( v1.printouts[depends_on_property] ) do
					nodes[v1.fulltext].dependencies[v2.fulltext] = true
				end
				nodes[v1.fulltext].projects = {}
				for k2,v2 in pairs ( v1.printouts[project_property] ) do
					nodes[v1.fulltext].projects[v2] = true
				end
				nodes[v1.fulltext].column = column
				nodes[v1.fulltext].tags = v1.printouts[tag_property]
			end
		end
	end
   return nodes
end

function p.getPageName( title )
	return string.sub( title, string.find( title, ':' ) + 1 )
end

function p.contains( t, value )
	for k,v in pairs ( t ) do
		if v == value then
			return true
		end
	end
	return false
end

function p.drawGraph( category, depends_on_property, status_property,
	owner_property, project_property, column_property, tag_property, filter,
	unlimited )
	local nodes = p.getNodes( category, depends_on_property, status_property,
		owner_property, project_property, column_property, tag_property,
		filter, unlimited )
	local s = 'graph LR\n'

	for k1,v1 in pairs( nodes ) do
		local name = p.getPageName( k1 )
		if v1.projects['Epic'] or v1.projects['Multi-Content-Revisions (Deployment)'] then
			s = s .. name .. '("' .. v1.displaytitle .. '")\n';
		else
			s = s .. name .. '["' .. v1.displaytitle .. '"]\n';
		end
		s = s .. 'click ' .. name .. ' "' .. v1.fullurl .. '"\n'
		if  v1.projects['Deployment'] then
			s = s .. 'class ' .. name .. ' mermaid-deployment\n'
		end
		if v1.status ~= 'open' and v1.status ~= 'stalled' then
			s = s .. 'class ' .. name .. ' mermaid-done\n'
		elseif v1.column == 'In Progress' or v1.column == 'Doing' then
			s = s .. 'class ' .. name .. ' mermaid-in-progress\n'
		elseif v1.column == 'Ready' or v1.column == 'Inbox' then
			s = s .. 'class ' .. name .. ' mermaid-ready\n'
		elseif v1.column == 'Watching' then
			s = s .. 'class ' .. name .. ' mermaid-watching\n'
		elseif v1.column == 'Blocked' then
			s = s .. 'class ' .. name .. ' mermaid-blocked\n'
		elseif v1.column == 'Needs Review' or v1.column == 'Waiting for Review' then
			s = s .. 'class ' .. name .. ' mermaid-needs-review\n'
		elseif v1.column == 'Needs Testing' then
			s = s .. 'class ' .. name .. ' mermaid-needs-testing\n'
		elseif v1.column == 'Epic' then
			s = s .. 'class ' .. name .. ' mermaid-epic\n'
		else
			s = s .. 'class ' .. name .. ' mermaid-other\n'
		end
	end
	for k1,v1 in pairs( nodes ) do
		for k2, v2 in pairs ( v1.dependencies ) do
			if ( nodes[k2] ) then
				s = s .. p.getPageName( k2 ) .. '==>' .. p.getPageName( k1 ) .. '\n'
			end
		end
	end
	return s
end

function p.pert_chart(frame)
	local filter = frame.args[1] or ''
	local s = p.drawGraph( 'Phabricator Tasks', 'Subtask', 'Status', 'Owner', 'Project', 'MCR Column', 'Tag', filter, true )
	return '<div style="width:100%;text-align:center;font-size:20pt;font-weight:bold;">' ..
		frame:callParserFunction{ name = '#mermaid', args = { s, 'config.flowchart.curve=basis', 'config.flowchart.useMaxWidth=false' } } .. '</div>'
end

function p.pert_chart_limited(frame)
	local filter = frame.args[1] or ''
	local s = p.drawGraph( 'Phabricator Tasks', 'Subtask', 'Status', 'Owner', 'Project', 'MCR Column', 'Tag', filter, false )
	return '<div style="width:100%;text-align:center;font-size:20pt;font-weight:bold;">' ..
		frame:callParserFunction{ name = '#mermaid', args = { s, 'config.flowchart.curve=basis', 'config.flowchart.useMaxWidth=false' } } .. '</div>'
end

return p