Module:TemplateData: Difference between revisions
(Remove more dependencies) |
m (1 revision imported) |
(No difference)
| |
Latest revision as of 22:04, 7 August 2018
local TemplateData = { serial = "2017-11-06",
suite = "TemplateData" }
local plaintext = require("Module:Plain text") --[=[ improve template:TemplateData ]=] local Config = {
-- multiple #invoke option names mapped into unique internal fields cat = "strange", classNoNumTOC = "suppressTOCnum",
-- classParams = "classTable",
cssParams = "stylesTable", cssParWrap = "stylesTabWrap", debug = false, docpageCreate = "suffix", docpageDetect = "subpage", msgDescMiss = "solo",
-- classTable = false, -- class for params table
loudly = false, -- show exported element, etc. solo = false, -- complaint on missing description strange = false, -- title of maintenance category stylesTable = false, -- styles for params table stylesTabWrap = false, -- styles for params table wrapper subpage = false, -- pattern to identify subpage suffix = false, -- subpage creation scheme suppressTOCnum = false -- class for TOC number suppression
} local Data = {
div = false, --
got = false, -- table, initial templatedata object heirs = false, -- table, params that are inherited less = false, -- main description missing lasting = false, -- old syntax encounteredlazy = false, -- doc mode; do not generate effective ", j, true )
if k then
r = mw.text.trim( s:sub( j + 1, k - 1 ) )
end
end
return r
end -- find()
local function flat( adjust )
-- Remove formatting from text string
-- Parameter:
-- arglist -- string, to be stripped, or nil
-- Returns string, or nil
local r
if adjust then
r = adjust:gsub( "\n", " " )
if r:find( "<noexport>", 1, true ) then
r = r:gsub( "<noexport>(.*)</noexport>", "" )
end
r = plaintext._main(r)
if r:find( "&", 1, true ) then
r = mw.text.decode( r )
end
end
return r
end -- flat()
local function flush()
-- JSON encode narrowed input; obey unnamed (numerical) parameters
-- Returns <templatedata> JSON string
local r
if Data.tag then
r = mw.text.jsonEncode( Data.tag ):gsub( "%}$", "," )
else
r = "{"
end
r = r .. "\n\"params\":{"
if Data.order then
local sep = ""
local s
for i = 1, #Data.order do
s = Data.order[ i ]
r = string.format( "%s%s\n%s:%s",
r,
sep,
mw.text.jsonEncode( s ),
mw.text.jsonEncode( Data.params[ s ] ) )
sep = ",\n"
end -- for i = 1, #Data.order
end
r = r .. "\n}\n}"
return r
end -- flush()
local function focus( access )
-- Check components; focus multilingual description, build trees
-- Parameter:
-- access -- string, name of parameter, nil for root
local f = function ( a, at )
local r
if at then
r = string.format( "params.%s", at )
else
r = "root"
end
if a then
r = string.format( "%s.%s", r, a )
end
return r
end
local parent
if access then
parent = Data.got.params[ access ]
else
parent = Data.got
end
if type( parent ) == "table" then
local elem, got, permit, s, scope, slot, tag, target
if access then
permit = Permit.params
if type( access ) == "number" then
slot = tostring( access )
else
slot = access
end
else
permit = Permit.root
end
for k, v in pairs( parent ) do
scope = permit[ k ]
if scope then
s = type( v )
if s == "string" then
v = mw.text.trim( v )
end
if scope:find( s, 1, true ) then
if scope:find( "I18N", 1, true ) then
if s == "string" then
elem = handleNoexportWhitespace( v )
else
local translated
v, translated = faraway( v )
if v then
if translated and
k == "description" then
elem = { [ 1 ] = handleNoexportWhitespace( v ),
[ 2 ] = translated }
else
elem = handleNoexportWhitespace( v )
end
else
elem = false
end
end
if v then
if scope:find( "nowiki", 1, true ) then
elem = mw.text.nowiki( v )
else
v = flat( v )
end
end
else
if k == "params" and not access then
v = nil
elem = nil
elseif k == "format" and not access then
v = mw.text.decode( v )
elem = v
elseif k == "inherits" then
elem = v
if not Data.heirs then
Data.heirs = { }
end
Data.heirs[ slot ] = v
v = nil
elseif s == "string" then
v = mw.text.nowiki( v )
elem = v
else
elem = v
end
end
if type( elem ) ~= "nil" then
if not target then
if access then
if not Data.tree.params then
Data.tree.params = { }
end
Data.tree.params[ slot ] = { }
target = Data.tree.params[ slot ]
else
Data.tree = { }
target = Data.tree
end
end
target[ k ] = elem
elem = false
end
if type( v ) ~= "nil" then
if not tag then
if access then
if not Data.params then
Data.params = { }
end
Data.params[ slot ] = { }
tag = Data.params[ slot ]
else
Data.tag = { }
tag = Data.tag
end
end
tag[ k ] = v
end
else
s = string.format( "Type %s bad for %s",
scope, f( k, slot ) )
Fault( s )
end
else
Fault( "Unknown component " .. f( k, slot ) )
end
end -- for k, v
else
Fault( f() .. " needs to be of object type" )
end
end -- focus()
local function format()
-- Build presented documentation-- Returns
local r = mw.html.create( "div" )
local s = feasible( Data.tree, true )
if s then
r:node( s )
end
if Data.leading then
local toc = mw.html.create( "div" )
if Config.suppressTOCnum then
toc:addClass( Config.suppressTOCnum )
end
toc:css( "margin-top", "0.5em" )
:wikitext( "" )
r:newline()
:node( toc )
:newline()
end
s = features()
if s then
if Data.leading then
r:node( mw.html.create( "h2" )
:wikitext( getLocalizedText( "doc-params" ) ) )
:newline()
end
r:node( s )
end
if Data.tree and Data.tree.format then
local e, style
s = Data.tree.format:lower( Data.tree.format )
if s == "inline" or s == "block" then
style = "i"
else
style = "code"
end
r:node( mw.html.create( "p" )
:wikitext( "Format: " )
:node( mw.html.create( style )
:wikitext( s ) ) )
end
return r
end -- format()
local function free()
-- Remove JSON comment lines
Data.source:gsub( "([{,\"'])(%s*\n%s*//.*\n%s*)([},\"'])",
"%1%3" )
end -- free()
local function full()
-- Build HTML table for display from JSON data, and append an invisible
-- <templatedata> block.
Data.div = mw.html.create( "div" )
:addClass( "mw-templatedata-doc-wrap" )
focus()
if Data.tag then
if type( Data.got.params ) == "table" then
for k, v in pairs( Data.got.params ) do
focus( k )
end -- for k, v
if Data.heirs then
fathers()
end
end
end
Data.div:node( format() )
if not Data.lazy then
Data.slim = flush()
if TemplateData.frame then
local div = mw.html.create( "div" )
local tdata = { [ 1 ] = "templatedata",
[ 2 ] = Data.slim }
Data.strip = TemplateData.frame:callParserFunction( "#tag",
tdata )
div:wikitext( Data.strip )
if Config.loudly then
-- Display raw templatedata table all the time.
Data.div:node( mw.html.create( "hr" ) )
Data.div:node( div )
else
-- Creates an expand link to check raw templatedata table.
local wrapper = mw.html.create( "div" )
wrapper:addClass( "mw-collapsible" )
wrapper:addClass( "mw-collapsed" )
wrapper:css( "font-size", "85%" )
div:addClass( "mw-collapsible-content" )
wrapper:wikitext( "Test of raw TemplateData output: " )
wrapper:node( div )
Data.div:node( wrapper )
end
end
end
end -- full()
local function furnish( adapt, arglist )
-- Called by f, this function is the first to do any real work when the -- module is invoked. -- Parameter: -- adapt -- table, #invoke parameters -- arglist -- table, template parameters -- Returns string
--local spy=""
local source
for k, v in pairs( Config ) do
if adapt[ k ] and adapt[ k ] ~= "" then
Config[ v ] = adapt[ k ]
end
end -- for k, v
Config.loudly = faculty( arglist.debug or adapt.debug )
--if mw.site.server:find( "//de.wikipedia.beta.wmflabs.org", 1, true ) then -- Config.loudly = true --end
Data.lazy = faculty( arglist.lazy ) and not Config.loudly
Data.leading = faculty( arglist.TOC )
if arglist.JSON then
source = arglist.JSON
elseif arglist[ 1 ] then
local s = mw.text.trim( arglist[ 1 ] )
local start = s:sub( 1, 1 )
if start == "<" then
Data.strip = s
elseif start == "{" then
source = s
elseif mw.ustring.sub( s, 1, 8 ) ==
mw.ustring.char( 127, 39, 34, 96, 85, 78, 73, 81 ) then -- ' " ` U N I Q
Data.strip = s
end
end
if not source then
Data.title = mw.title.getCurrentTitle()
source = find()
if not source and
Config.subpage and Config.suffix and
not Data.title.text:match( Config.subpage ) then
local s = string.format( Config.suffix,
Data.title.prefixedText )
Data.title = mw.title.new( s )
if Data.title.exists then
source = find()
end
end
--if source and -- ( source:find( "|", 1, true ) or -- source:find( "}}", 1, true ) ) then -- -- <ref --spy=string.format( "", Config.strange ) --end
end
if not Data.lazy and Config.subpage then
if not Data.title then
Data.title = mw.title.getCurrentTitle()
end
Data.lazy = Data.title.text:match( Config.subpage )
end
TemplateData.getPlainJSON( source )
return finalize()
--return spy .. finalize() end -- furnish()
TemplateData.failsafe = function ( assert ) -- Checks the age of this implementation against some minimum ("assert").
local r
if not assert or assert <= TemplateData.serial then
r = TemplateData.serial
else
r = false
end
return r
end -- TemplateData.failsafe()
TemplateData.getPlainJSON = function ( adapt )
-- Reduce enhanced JSON data to plain text localized JSON
-- Parameter:
-- adapt -- string, with enhanced JSON
-- Returns string, or not
if type( adapt ) == "string" then
Data.source = adapt
free()
Data.got = mw.text.jsonDecode( Data.source )
if Data.got then
full()
if Data.lasting then
Fault( "deprecated type syntax" )
end
if Data.less then
Fault( Config.solo )
end
elseif not Data.strip then
Fault( "fatal JSON error" )
end
end
return Data.slim
end -- TemplateData.getPlainJSON()
TemplateData.test = function ( adapt, arglist )
TemplateData.frame = mw.getCurrentFrame() return furnish( adapt, arglist )
end -- TemplateData.test()
-- Export local p = { }
p.f = function ( frame )
-- The entry point for templates invoking the module.
-- Just wraps furnish in an exception handler.
local lucky, result
TemplateData.frame = frame
lucky, result = pcall( furnish, frame.args, frame:getParent().args )
if not lucky then
Fault( "INTERNAL: " .. result )
result = failures()
end
return result
end -- p.f()
p.failsafe = function ( frame )
-- Versioning interface
local s = type( frame )
local since
if s == "table" then
since = frame.args[ 1 ]
elseif s == "string" then
since = frame
end
if since then
since = mw.text.trim( since )
if since == "" then
since = false
end
end
return TemplateData.failsafe( since ) or ""
end -- p.failsafe()
p.TemplateData = function ()
-- Module interface return TemplateData
end
return p