モジュール:サンドボックス/Ef3/TemplateDataGenerator
表示
モジュールの解説[作成]
--[=[ 2013-08-05
{{TemplateDataGenerator}}
Basic idea by [[w:en:User:Salix alba]]
]=]
local config = {
luxury = false, -- default alphabetical order for parameter list
start = false, -- preceeding lines
shift = " ", -- (not used now) indentation, like " " or "\t"
suffix = false, -- following lines
scheme = [=["%s":
{ "label": "%s",
"description": "",
"type": "string",
"required": false
}]=]
-- config.scheme has placeholders %s
-- for the parameter name and for "label".
-- One of various indentation styles.
-- Feel free to compose a different one, also using config.shift etc.
};
local function factory( analyze, alphabetical )
-- Make parameter sequence from template source text
-- analyze -- string; template source text
-- alphabetical -- boolean or nil; sort parameter list
-- Return:
-- table (sequence) with parameter names
local i, s;
local r = { };
for s in analyze:gmatch( "{{{([^|}\n]+)" ) do
for i = 1, #r do
if r[ i ] == s then
s = false;
break; -- for i
end
end -- for i
if s then
table.insert( r, s );
end
end -- for s in :gmatch()
if alphabetical then
table.sort( r, nil );
end
return r;
end -- factory()
local function format( analyze, alphabetical )
-- Make JSON code from template source text
-- analyze -- string; template source text
-- alphabetical -- boolean or nil; sort parameter list
-- Return:
-- string with JSON code
-- Uses:
-- > config.shift
-- > config.scheme
-- factory()
local i;
local params = factory( analyze, alphabetical );
local r = '{ "description": "",\n';
-- local shift = config.shift or ""; -- currently unused
local start = " ";
local show, symbol;
r = r .. ' "params": { ';
for i = 1, #params do
if i > 1 then
r = string.format( "%s,\n%s ", r, start );
end
symbol = params[ i ];
if mw.ustring.match( symbol, "^%u%u" ) then
show = mw.ustring.sub( symbol, 1, 1 ) ..
mw.ustring.lower( mw.ustring.sub( symbol, 2 ) );
else
show = "";
end
r = r .. string.format( config.scheme, symbol, show );
-- common JSON pattern is ASCII; string.format() will do
end -- for i
r = string.format( "%s\n%s}\n}", r, start );
return r;
end -- format()
local function fun( attempt, alphabetical )
-- Retrieve used template params and build TemplateData skeleton
-- Precondition:
-- attempt -- mw.title object; related to template code
-- alphabetical -- boolean or nil; sort parameter list
-- Return:
-- string to be applied
-- Uses:
-- > config.luxury
-- > config.start
-- > config.suffix
-- format()
local r;
local source = string.match( attempt.baseText .. "/",
"^([^/]+)/" );
-- ensure top page in NS with no subpage property
-- note that pattern is ASCII; string.match() will do
local title = mw.title.makeTitle( attempt.namespace, source );
if title.exists then
local luxury = config.luxury;
local spec = "%s<templatedata>\n%s\n</templatedata>\n%s";
if type( alphabetical ) == "boolean" then
luxury = alphabetical;
end
if config.start then
r = config.start .. "\n";
else
r = "";
end
r = string.format( spec,
r,
format( title:getContent(), luxury ),
config.suffix or "" );
-- note that format spec is ASCII only; string.format() will do
else -- test only
r = "ERROR * no page " .. title.fullText;
end
return r;
end -- fun()
-- Export
local p = {};
function p.getBlock( pagetitle, namespace, alphabetical )
-- Precondition:
-- pagetitle -- string; page title related to template code
-- namespace -- string, number or nil; namespace (Template:)
-- alphabetical -- boolean or nil; sort parameter list
-- Uses:
-- fun()
local title = mw.title.makeTitle( namespace or 10, pagetitle );
local lucky, r = pcall( fun, title, alphabetical );
return r;
end -- .getBlock()
function p.f( frame )
-- Precondition:
-- frame -- object
-- Invoked on a template page or template subpage.
-- Uses:
-- fun()
local luxury;
local parental = frame:getParent().args;
local sort = parental[ 1 ] or parental[ "1" ] or parental.sort;
if sort then
luxury = ( tonumber( sort) == 1 );
end
local lucky, r = pcall( fun, mw.title.getCurrentTitle(), luxury );
-- return "<pre>" .. r .. "</pre>";
return r;
end -- .f()
return p;