Модуль:TemplateDataDoc: различия между версиями
Перейти к навигации
Перейти к поиску
Mansur700 (обсуждение | вклад) Нет описания правки |
Mansur700 (обсуждение | вклад) Нет описания правки |
||
Строка 1: | Строка 1: | ||
local docSubPage = mw.message.new( 'Templatedata-doc-subpage' ):plain(); | local docSubPage = mw.message.new( 'Templatedata-doc-subpage' ):plain(); | ||
p = {}; | local p = {}; | ||
local lastNumber = 0; | |||
-- Enable/disable additional spacing for block-formatted templates | |||
local formatBlockSpaces = true; | |||
local noDocNote = 'TemplateDataDoc: Запишите страницу для отображения заполненного шаблона.'; | |||
local status, data = pcall( mw.text.jsonDecode, | function p.processJson( json ) | ||
local status, data = pcall( mw.text.jsonDecode, json ); | |||
if status == false then | if status == false then | ||
return nil; | return nil; | ||
Строка 30: | Строка 27: | ||
'nocoord', | 'nocoord', | ||
'nocatcoord', | 'nocatcoord', | ||
'Ширина', | |||
'ширина', | |||
'Ширина изображения', | |||
'ширина изображения', | |||
'Ширина логотипа', | |||
'ширина логотипа', | |||
}; | }; | ||
for _, param in ipairs( deprecatedParams ) do | for _, param in ipairs( deprecatedParams ) do | ||
if data[ 'params' ][ param ] ~= nil then | if data[ 'params' ][ param ] ~= nil then | ||
data[ 'params' ][ param ][ 'deprecated' ] = ' | data[ 'params' ][ param ][ 'deprecated' ] = '-'; | ||
end | end | ||
end | end | ||
Строка 40: | Строка 43: | ||
end | end | ||
function p. | function p.getTemplateData( pageName ) | ||
local | local title = mw.title.makeTitle( 0, pageName ); | ||
if not title or not title.exists or not title:getContent() then | |||
return false; | |||
local | end; | ||
local json = mw.ustring.match( title:getContent(), '<[Tt]emplate[Dd]ata%s*>(.*)</[Tt]emplate[Dd]ata%s*>' ); | |||
if not json then | |||
return nil; | |||
end | |||
return p.processJson( json ) | |||
end | |||
function p.getValue( data, key ) | |||
if data[ key ] then | |||
return data[ key ]; | |||
end | |||
-- Numbered keys return as numbers | |||
local nkey = tonumber( key ); | |||
if nkey ~= nil and data[ nkey ] then | |||
return data[ nkey ]; | |||
end | end | ||
return {}; | |||
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': [[phab:T205438]] | |||
local templateFormat = | function p.convertFormatString( rawTemplateFormat ) | ||
local templateFormat = rawTemplateFormat or 'inline'; | |||
local isBlockFormatted = false; | local isBlockFormatted = false; | ||
if templateFormat == 'block' then | if templateFormat == 'block' then | ||
Строка 74: | Строка 82: | ||
templateFormat = '{{_|_=_}}'; | templateFormat = '{{_|_=_}}'; | ||
end | end | ||
return templateFormat, isBlockFormatted; | |||
end | |||
function p.getFormatParts( rawTemplateFormat, templateName ) | |||
local templateFormat, isBlockFormatted = p.convertFormatString( rawTemplateFormat ); | |||
local nameFormat = mw.ustring.match( templateFormat, '^[^|]+' ); | local nameFormat = mw.ustring.match( templateFormat, '^[^|]+' ); | ||
local paramKeyFormat = mw.ustring.match( templateFormat, '%|[^=]+=' ); | local paramKeyFormat = mw.ustring.match( templateFormat, '%|[^=]+=' ); | ||
Строка 79: | Строка 93: | ||
paramValueFormat = mw.ustring.sub( paramValueFormat, 2 ); | paramValueFormat = mw.ustring.sub( paramValueFormat, 2 ); | ||
local endFormat = mw.ustring.match( templateFormat, '%}%}.*$' ); | local endFormat = mw.ustring.match( templateFormat, '%}%}.*$' ); | ||
local startFormat = mw.ustring.gsub( nameFormat, '_', templateName ); | |||
return isBlockFormatted, startFormat, endFormat, paramKeyFormat, paramValueFormat; | |||
end | |||
function p.formatKeyValue( key, parameterData, formatData ) | |||
if parameterData[ 'deprecated' ] then | |||
local | return ''; | ||
end | |||
local args = formatData.args; | |||
if | local parameterName = key; | ||
local nkey = tonumber(key); | |||
-- Add additional spacing to string keys | |||
if formatBlockSpaces and formatData.isBlockFormatted then | |||
if nkey == nil or lastNumber ~= nkey - 1 then | |||
while mw.ustring.len( key ) < formatData.parameterLength do | |||
key = key .. ' '; | |||
end | |||
end | end | ||
end | |||
-- Remove numbering for adjacent numbered keys | |||
if nkey ~= nil and lastNumber == nkey - 1 then | |||
key = ''; | |||
lastNumber = nkey; | |||
end | |||
local value = ''; | |||
if formatData.valueKey == 'example' and parameterData[ 'example' ] then | |||
-- Example | |||
value = parameterData[ 'example' ]; | |||
else | |||
if formatData.valueKey == 'description' and parameterData[ 'description' ] then | |||
-- Description | |||
value = parameterData[ 'description' ]; | |||
if value ~= '' then | |||
value = '<!-- ' .. value .. ' -->'; | |||
end | end | ||
elseif parameterData[ 'autovalue' ] then | |||
-- Autovalue | |||
value = parameterData[ 'autovalue' ]; | |||
end | |||
if args[ '$' .. parameterName ] and args[ '$' .. parameterName ] ~= '' then | |||
-- Custom values from template call | |||
value = args[ '$' .. parameterName ]; | |||
end | |||
end | |||
local formattedKey = mw.ustring.gsub( formatData.paramKeyFormat, '_+', key, 1 ); | |||
if key == '' then | |||
formattedKey = mw.ustring.gsub( formattedKey, '=', '' ); | |||
end | |||
return formattedKey .. mw.ustring.gsub( formatData.paramValueFormat, '_', value, 1 ); | |||
end | |||
function p.generateBlankCode( templateData, templateName, args ) | |||
if templateData == false then | |||
return '{{' .. templateName .. '}}'; | |||
end | |||
local parameterLength = 0; | |||
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do | |||
local parameterData = p.getValue( templateData[ 'params' ], parameterName ); | |||
if not parameterData[ 'deprecated' ] then | |||
local length = mw.ustring.len( parameterName ); | |||
if length > parameterLength then | |||
parameterLength = length; | |||
end | end | ||
end | |||
end | |||
local isBlockFormatted, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName ); | |||
local out = startFormat; | |||
lastNumber = 0; | |||
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do | |||
local parameterData = p.getValue( templateData[ 'params' ], parameterName ); | |||
if parameterData[ 'inherits' ] then | |||
parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] ); | |||
end | end | ||
out = out .. p.formatKeyValue( parameterName, parameterData, { | |||
args = args, | |||
valueKey = ( args[ 'description' ] and 'description' or nil ), | |||
isBlockFormatted = isBlockFormatted, | |||
parameterLength = parameterLength, | |||
paramKeyFormat = paramKeyFormat, | |||
paramValueFormat = paramValueFormat, | |||
} ); | |||
end | end | ||
return out .. endFormat; | |||
end | end | ||
function p. | function p.generateBlank( frame ) | ||
local frame = mw.getCurrentFrame(); | local frame = mw.getCurrentFrame(); | ||
local args = frame | local getArgs = require( 'Module:Arguments' ).getArgs; | ||
local args = getArgs( frame ); | |||
local templateName = frame.args[ 1 ]; | local templateName = frame.args[ 1 ]; | ||
table.remove( args, 1 ); | |||
local docPage = 'Template:' .. templateName .. '/' .. docSubPage; | local docPage = 'Template:' .. templateName .. '/' .. docSubPage; | ||
local templateData = getTemplateData( docPage ); | local templateData = p.getTemplateData( docPage ); | ||
local out = p.generateBlankCode( templateData, templateName, args ); | |||
local previewNote = '' | |||
if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then | |||
previewNote = '<div class="warningbox">' .. noDocNote .. '</div>'; | |||
end | |||
local | return previewNote .. frame:extensionTag{ name = 'pre', content = out }; | ||
end | |||
function p.generateExampleCode( templateData, templateName, args ) | |||
if templateData == false then | |||
return '{{' .. templateName .. '}}'; | |||
end | |||
local parameterLength = 0; | |||
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do | for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do | ||
local parameterData = templateData[ 'params' ] | local parameterData = p.getValue( templateData[ 'params' ], parameterName ); | ||
if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then | if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then | ||
local length = mw.ustring.len( parameterName ); | local length = mw.ustring.len( parameterName ); | ||
if length > | if length > parameterLength then | ||
parameterLength = length; | |||
end | end | ||
end | end | ||
end | end | ||
local isBlockFormatted, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName ); | |||
local out = startFormat; | |||
local isBlockFormatted | |||
local | |||
lastNumber = 0; | |||
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do | for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do | ||
local parameterData = templateData[ 'params' ] | local parameterData = p.getValue( templateData[ 'params' ], parameterName ); | ||
if parameterData[ 'inherits' ] then | if parameterData[ 'inherits' ] then | ||
parameterData = templateData[ 'params' ] | parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] ); | ||
end | end | ||
if parameterData[ 'example | if parameterData[ 'example' ] then | ||
out = out .. p.formatKeyValue( parameterName, parameterData, { | |||
args = args, | |||
valueKey = 'example', | |||
isBlockFormatted = isBlockFormatted, | |||
parameterLength = parameterLength, | |||
paramKeyFormat = paramKeyFormat, | |||
paramValueFormat = paramValueFormat, | |||
} ); | |||
end | end | ||
end | end | ||
out = out .. | 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 ); | |||
local previewNote = '' | |||
if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then | |||
previewNote = '<div class="warningbox">' .. noDocNote .. '</div>'; | |||
end | |||
return frame:preprocess( out ) .. frame:extensionTag{ name = 'pre', content = out }; | return previewNote .. frame:preprocess( out ) .. frame:extensionTag{ name = 'pre', content = out }; | ||
end | end | ||
return p; | return p; |
Текущая версия от 20:39, 4 февраля 2022
Модуль для работы с TemplateData и автоматической генерации заготовок для копирования и примеров использования шаблонов на основе её.
Для корректной сортировки параметров в TemplateData должен содержаться массив paramOrder
. При редактировании через визуальный интерфейс он добавляется в момент перетаскивания параметров вверх-вниз в списке.
Методы[править код]
Модуль для работы с TemplateData и автоматической генерации заготовок для копирования и примеров использования шаблонов на основе её.
Для корректной сортировки параметров в TemplateData должен содержаться массив paramOrder
. При редактировании через визуальный интерфейс он добавляется в момент перетаскивания параметров вверх-вниз в списке.
Методы[править код]
Внешние[править код]
- generateBlank( frame ) — вывод заготовки для вставки шаблона в статью (см. {{заготовка шаблона}})
- generateExample( frame ) — вывод примера использования шаблона (см. {{пример шаблона}})
Внутренние[править код]
- getTemplateData( pageName ) — парсинг TemplateData с указанной страницы
Внутренние[править код]
- getTemplateData( pageName ) — парсинг TemplateData с указанной страницы
local docSubPage = mw.message.new( 'Templatedata-doc-subpage' ):plain();
local p = {};
local lastNumber = 0;
-- Enable/disable additional spacing for block-formatted templates
local formatBlockSpaces = true;
local noDocNote = 'TemplateDataDoc: Запишите страницу для отображения заполненного шаблона.';
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 false;
end;
local json = mw.ustring.match( title:getContent(), '<[Tt]emplate[Dd]ata%s*>(.*)</[Tt]emplate[Dd]ata%s*>' );
if not json then
return nil;
end
return p.processJson( json )
end
function p.getValue( data, key )
if data[ key ] then
return data[ key ];
end
-- Numbered keys return as numbers
local nkey = tonumber( key );
if nkey ~= nil and data[ nkey ] then
return data[ nkey ];
end
return {};
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': [[phab:T205438]]
function p.convertFormatString( rawTemplateFormat )
local templateFormat = rawTemplateFormat or 'inline';
local isBlockFormatted = false;
if templateFormat == 'block' then
templateFormat = '{{_\n| _ = _\n}}';
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.formatKeyValue( key, parameterData, formatData )
if parameterData[ 'deprecated' ] then
return '';
end
local args = formatData.args;
local parameterName = key;
local nkey = tonumber(key);
-- Add additional spacing to string keys
if formatBlockSpaces and formatData.isBlockFormatted then
if nkey == nil or lastNumber ~= nkey - 1 then
while mw.ustring.len( key ) < formatData.parameterLength do
key = key .. ' ';
end
end
end
-- Remove numbering for adjacent numbered keys
if nkey ~= nil and lastNumber == nkey - 1 then
key = '';
lastNumber = nkey;
end
local value = '';
if formatData.valueKey == 'example' and parameterData[ 'example' ] then
-- Example
value = parameterData[ 'example' ];
else
if formatData.valueKey == 'description' and parameterData[ 'description' ] then
-- Description
value = parameterData[ 'description' ];
if value ~= '' then
value = '<!-- ' .. value .. ' -->';
end
elseif parameterData[ 'autovalue' ] then
-- Autovalue
value = parameterData[ 'autovalue' ];
end
if args[ '$' .. parameterName ] and args[ '$' .. parameterName ] ~= '' then
-- Custom values from template call
value = args[ '$' .. parameterName ];
end
end
local formattedKey = mw.ustring.gsub( formatData.paramKeyFormat, '_+', key, 1 );
if key == '' then
formattedKey = mw.ustring.gsub( formattedKey, '=', '' );
end
return formattedKey .. mw.ustring.gsub( formatData.paramValueFormat, '_', value, 1 );
end
function p.generateBlankCode( templateData, templateName, args )
if templateData == false then
return '{{' .. templateName .. '}}';
end
local parameterLength = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if not parameterData[ 'deprecated' ] then
local length = mw.ustring.len( parameterName );
if length > parameterLength then
parameterLength = length;
end
end
end
local isBlockFormatted, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName );
local out = startFormat;
lastNumber = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'inherits' ] then
parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] );
end
out = out .. p.formatKeyValue( parameterName, parameterData, {
args = args,
valueKey = ( args[ 'description' ] and 'description' or nil ),
isBlockFormatted = isBlockFormatted,
parameterLength = parameterLength,
paramKeyFormat = paramKeyFormat,
paramValueFormat = paramValueFormat,
} );
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 );
local previewNote = ''
if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then
previewNote = '<div class="warningbox">' .. noDocNote .. '</div>';
end
return previewNote .. frame:extensionTag{ name = 'pre', content = out };
end
function p.generateExampleCode( templateData, templateName, args )
if templateData == false then
return '{{' .. templateName .. '}}';
end
local parameterLength = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then
local length = mw.ustring.len( parameterName );
if length > parameterLength then
parameterLength = length;
end
end
end
local isBlockFormatted, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName );
local out = startFormat;
lastNumber = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'inherits' ] then
parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] );
end
if parameterData[ 'example' ] then
out = out .. p.formatKeyValue( parameterName, parameterData, {
args = args,
valueKey = 'example',
isBlockFormatted = isBlockFormatted,
parameterLength = parameterLength,
paramKeyFormat = paramKeyFormat,
paramValueFormat = paramValueFormat,
} );
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 );
local previewNote = ''
if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then
previewNote = '<div class="warningbox">' .. noDocNote .. '</div>';
end
return previewNote .. frame:preprocess( out ) .. frame:extensionTag{ name = 'pre', content = out };
end
return p;