Module:TemplateDataDoc

local docSubPage = mw.message.new( 'Templatedata-doc-subpage' ):plain;

local p = {};

function p.processJson( json ) local status, data = pcall( mw.text.jsonDecode, json ); if status == false then return nil; end

if not data[ 'paramOrder' ] then data[ 'paramOrder' ] = {}; for paramName, paramData in pairs( data[ 'params' ] ) do			table.insert( data[ 'paramOrder' ], paramName ); end end local deprecatedParams = { 'nocat', 'nocoord', 'nocatcoord', };	for _, param in ipairs( deprecatedParams ) do		if data[ 'params' ][ param ] ~= nil then data[ 'params' ][ param ][ 'deprecated' ] = '-'; end end

return data; end

function p.getTemplateData( pageName ) local title = mw.title.makeTitle( 0, pageName ); if not title or not title.exists or not title:getContent then return nil; end;

local json = mw.ustring.match( title:getContent, '(.*)' ); if not json then return nil; end return p.processJson( json ) end

-- See https://phabricator.wikimedia.org/diffusion/ETDA/browse/master/Specification.md?as=remarkup -- We need a global format value for the 'block' and 'inline': T205438 function p.convertFormatString( rawTemplateFormat ) local templateFormat = rawTemplateFormat; local isBlockFormatted = false; if templateFormat == 'block' then templateFormat = ''; isBlockFormatted = true; elseif templateFormat == 'inline' then templateFormat = ''; end return templateFormat, isBlockFormatted; end

function p.getFormatParts( rawTemplateFormat, templateName ) local templateFormat, isBlockFormatted = p.convertFormatString( rawTemplateFormat ); local nameFormat = mw.ustring.match( templateFormat, '^[^|]+' ); local paramKeyFormat = mw.ustring.match( templateFormat, '%|[^=]+=' ); local paramValueFormat = mw.ustring.match( templateFormat, '=[^}]+' ); paramValueFormat = mw.ustring.sub( paramValueFormat, 2 ); local endFormat = mw.ustring.match( templateFormat, '%}%}.*$' ); local startFormat = mw.ustring.gsub( nameFormat, '_', templateName ); return isBlockFormatted, startFormat, endFormat, paramKeyFormat, paramValueFormat; end

function p.generateBlankCode( templateData, templateName, args ) local paramaterLength = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do		local parameterData = templateData[ 'params' ][ parameterName ] or {}; if not parameterData[ 'deprecated' ] then local length = mw.ustring.len( parameterName ); if length > paramaterLength then paramaterLength = length; end end end

local isBlockFormatted, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName ); local out = startFormat;

local lastNumber = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do		local parameterData = templateData[ 'params' ][ parameterName ] or {}; if parameterData[ 'inherits' ] then parameterData = templateData[ 'params' ][ parameterData[ 'inherits' ] ] or {}; end if not parameterData[ 'deprecated' ] then local key = parameterName; local nkey = tonumber(key); if isBlockFormatted then if nkey == nil or lastNumber ~= nkey - 1 then while mw.ustring.len( key ) < paramaterLength do key = key .. ' ';					end end end if nkey ~= nil and lastNumber == nkey - 1 then key = ''; lastNumber = nkey; end local value = ''; if args[ 'description' ] == '1' and parameterData[ 'description' ] then value = parameterData[ 'description' ]; if value ~= '' then value = '&lt;!-- ' .. value .. ' --&gt;'; end elseif parameterData[ 'autovalue' ] then value = parameterData[ 'autovalue' ]; end if args[ '$' .. parameterName ] and args[ '$' .. parameterName ] ~= '' then value = args[ '$' .. parameterName ]; end local formattedKey = mw.ustring.gsub( paramKeyFormat, '_+', key, 1 ); if key == '' then formattedKey = mw.ustring.gsub( formattedKey, '=', '' ); end out = out .. formattedKey;

out = out .. mw.ustring.gsub( paramValueFormat, '_', value, 1 ); end end return out .. endFormat; end

function p.generateBlank( frame ) local frame = mw.getCurrentFrame; local getArgs = require( 'Module:Arguments' ).getArgs; local args = getArgs( frame ); local templateName = frame.args[ 1 ]; table.remove( args, 1 ); local docPage = 'Template:' .. templateName .. '/' .. docSubPage; local templateData = p.getTemplateData( docPage ); local out = p.generateBlankCode( templateData, templateName, args );

return frame:extensionTag{ name = 'pre', content = out }; end

function p.generateExampleCode( templateData, templateName, args ) local paramaterLength = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do		local parameterData = templateData[ 'params' ][ parameterName ] or {}; if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then local length = mw.ustring.len( parameterName ); if length > paramaterLength then paramaterLength = length; end end end

local isBlockFormatted, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName ); local out = startFormat;

local lastNumber = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do		local parameterData = templateData[ 'params' ][ parameterName ] or {}; if parameterData[ 'inherits' ] then parameterData = templateData[ 'params' ][ parameterData[ 'inherits' ] ] or {}; end if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then local key = parameterName; local nkey = tonumber( key ); if isBlockFormatted then if nkey == nil or lastNumber ~= nkey - 1 then while mw.ustring.len( key ) < paramaterLength do key = key .. ' ';					end end end if nkey ~= nil and lastNumber == nkey - 1 then key = ''; lastNumber = nkey; end

local value = parameterData[ 'example' ];

local formattedKey = mw.ustring.gsub( paramKeyFormat, '_+', key, 1 ); if key == '' then formattedKey = mw.ustring.gsub( formattedKey, '=', '' ); end out = out .. formattedKey;

out = out .. mw.ustring.gsub( paramValueFormat, '_', value, 1 ); end end return out .. endFormat; end

function p.generateExample( frame ) local frame = mw.getCurrentFrame; local args = frame.args; local templateName = frame.args[ 1 ]; local docPage = 'Template:' .. templateName .. '/' .. docSubPage; local templateData = p.getTemplateData( docPage ); local out = p.generateExampleCode( templateData, templateName, args ); return frame:preprocess( out ) .. frame:extensionTag{ name = 'pre', content = out }; end

return p;