Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Modül:TemplatePar

bullvar_katip

Administrator
Katılım
21 Mayıs 2024
Mesajlar
532,105
local TemplatePar = { serial = "2023-03-20", suite = "TemplatePar", item = 15393417, globals = { DateTime = 20652535, FileMedia = 24765326, Multilingual = 47541920, TemplUtl = 52364930, URLutil = 10859193 } } --[=[ Template parameter utility assert check count countNotEmpty downcase duplicates match valid verify TemplatePar failsafe ]=] local Local = { frame = false } local Failsafe = TemplatePar local GlobalMod = Local -- Module globals Local.messagePrefix = "lua-module-TemplatePar-" Local.L10nDef = {} Local.L10nDef.tr = { badPattern = "&#35;invoke:TemplatePar pattern syntax error", dupOpt = "&#35;invoke:TemplatePar repeated optional parameter", dupRule = "&#35;invoke:TemplatePar conflict key/pattern", empty = "Şablon hatası * zorunlu alan için tanımsız değer", invalid = "Şablon hatası * geçersiz parametre", invalidPar = "&#35;invoke:TemplatePar invalid parameter", minmax = "&#35;invoke:TemplatePar min > max", missing = "&#35;invoke:TemplatePar missing library", multiSpell = "Şablon hatası * parametrenin birden fazla yazımı", noMSGnoCAT = "&#35;invoke:TemplatePar neither message nor category", noname = "&#35;invoke:TemplatePar missing parameter name", notFound = "Şablon hatası * bulunmayan sayfa", tooLong = "Şablon hatası * parametre çok uzun", tooShort = "Şablon hatası * parametre çok kısa", unavailable = "Şablon hatası * parametre adı eksik", undefined = "Şablon hatası * zorunlu parametre eksik", unknown = "Şablon hatası * bilinmeyen parametre adı", unknownRule = "&#35;invoke:TemplatePar unknown rule" } Local.patterns = { [ "ASCII" ] = "^[ -~]*$", [ "ASCII+" ] = "^[ -~]+$", [ "ASCII+1" ] = "^[!-~]+$", [ "n" ] = "^[%-]?[0-9]*$", [ "n>0" ] = "^[0-9]*[1-9][0-9]*$", [ "N+" ] = "^[%-]?[1-9][0-9]*$", [ "N>0" ] = "^[1-9][0-9]*$", [ "x" ] = "^[0-9A-Fa-f]*$", [ "x+" ] = "^[0-9A-Fa-f]+$", [ "X" ] = "^[0-9A-F]*$", [ "X+" ] = "^[0-9A-F]+$", [ "0,0" ] = "^[%-]?[0-9]*,?[0-9]*$", [ "0,0+" ] = "^[%-]?[0-9]+,[0-9]+$", [ "0,0+?" ] = "^[%-]?[0-9]+,?[0-9]*$", [ "0.0" ] = "^[%-]?[0-9]*[%.]?[0-9]*$", [ "0.0+" ] = "^[%-]?[0-9]+%.[0-9]+$", [ "0.0+?" ] = "^[%-]?[0-9]+[%.]?[0-9]*$", [ ".0+" ] = "^[%-]?[0-9]*[%.]?[0-9]+$", [ "ID" ] = "^[A-Za-z]?[A-Za-z_0-9]*$", [ "ID+" ] = "^[A-Za-z][A-Za-z_0-9]*$", [ "ABC" ] = "^[A-Z]*$", [ "ABC+" ] = "^[A-Z]+$", [ "Abc" ] = "^[A-Z]*[a-z]*$", [ "Abc+" ] = "^[A-Z][a-z]+$", [ "abc" ] = "^[a-z]*$", [ "abc+" ] = "^[a-z]+$", [ "aBc+" ] = "^[a-z]+[A-Z][A-Za-z]*$", [ "w" ] = "^%S*$", [ "w+" ] = "^%S+$", [ "base64" ] = "^[A-Za-z0-9%+/]*$", [ "base64+" ] = "^[A-Za-z0-9%+/]+$", [ "aa" ] = "[%a%a].*[%a%a]", [ "pagename" ] = string.format( "^[^#<>%%[%%]|{}%c-%c%c]+$", 1, 31, 127 ), [ "ref" ] = string.format( "%c'%c`UNIQ%s%sref%s%s%sQINU`%c'%c", 127, 34, "%-", "%-", "%-", "%x+", "%-", 34, 127 ), [ "+" ] = "%S" } Local.boolean = { ["1"] = true, ["true"] = true, y = true, yes = true, on = true, ["0"] = true, ["false"] = true, ["-"] = true, n = true, no = true, off = true } Local.patternCJK = false local foreignModule = function ( access, advanced, append, alt, alert ) -- Fetch global module -- Precondition: -- access -- string, with name of base module -- advanced -- true, for require; else mw.loadData -- append -- string, with subpage part, if any; or false -- alt -- number, of wikidata item of root; or false -- alert -- true, for throwing error on data problem -- Postcondition: -- Returns whatever, probably table -- 2020-01-01 local storage = access local finer = function if append then storage = string.format( "%s/%s", storage, append ) end end local fun, lucky, r, suited if advanced then fun = require else fun = mw.loadData end GlobalMod.globalModules = GlobalMod.globalModules or { } suited = GlobalMod.globalModules[ access ] if not suited then finer lucky, r = pcall( fun, "Modül:" .. storage ) end if not lucky then if not suited and type( alt ) "number" and alt > 0 then suited string.format( "Q%d", alt ) suited mw.wikibase.getSitelink( suited ) GlobalMod.globalModules[ access ] suited or true end if type( suited ) "string" then storage = suited finer lucky, r = pcall( fun, storage ) end if not lucky and alert then error( "Missing or invalid page: " .. storage ) end end return r end -- foreignModule local function Foreign( access ) -- Access standardized library -- Precondition: -- access -- string, with name of base module -- Postcondition: -- Return library table, or not -- Uses: local r if Local[ access ] then r = Local[ access ] else local bib = foreignModule( access, true, false, TemplatePar.globals[ access ], false ) if type( bib ) "table" and type( bib[ access ] ) "function" then bib = bib[ access ] if type( bib ) == "table" then r = bib Local[ access ] = bib end end end return r end -- Foreign local function containsCJK( analyse ) -- Is any CJK character present? -- Precondition: -- analyse -- string -- Postcondition: -- Return false iff no CJK present -- Uses: -- >< Local.patternCJK -- mw.ustring.char -- mw.ustring.match local r = false if not Local.patternCJK then Local.patternCJK = mw.ustring.char( 91, 13312, 45, 40959, 131072, 45, 178207, 93 ) end if mw.ustring.match( analyse, Local.patternCJK ) then r = true end return r end -- containsCJK local function facility( accept, attempt ) -- Check string as possible file name or other source page -- Precondition: -- accept -- string; requirement -- file -- file+ -- file: -- file:+ -- image -- image+ -- image: -- image:+ -- attempt -- string; to be tested -- Postcondition: -- Return error keyword, or false -- Uses: -- Module:FileMedia -- Foreign -- FileMedia.isFile -- FileMedia.isType local r if attempt and attempt ~= "" then local FileMedia = Foreign( "FileMedia" ) if FileMedia and type( FileMedia.isFile ) "function" and type( FileMedia.isType ) "function" then local s, live = accept:match( "^([a-z]+)(:?)%+?$" ) if live then if FileMedia.isType( attempt, s ) then if FileMedia.isFile( attempt ) then r = false else r = "notFound" end else r = "invalid" end elseif FileMedia.isType( attempt, s ) then r = false else r = "invalid" end else r = "missing" end elseif accept:match( "%+$" ) then r = "empty" else r = false end return r end -- facility local function factory( say ) -- Retrieve localized message string in content language -- Precondition: -- say -- string; message ID -- Postcondition: -- Return some message string -- Uses: -- > Local.messagePrefix -- > Local.L10nDef -- mw.message.new -- mw.language.getContentLanguage -- Module:Multilingual -- Foreign -- TemplatePar.framing -- Multilingual.tabData local m = mw.message.new( Local.messagePrefix .. say ) local r = false if m:isBlank then local c = mw.language.getContentLanguage:getCode local l10n = Local.L10nDef[ c ] if l10n then r = l10n[ say ] else local MultiL = Foreign( "Multilingual" ) if MultiL and type( MultiL.tabData ) == "function" then local lang r, lang = MultiL.tabData( "I18n/Module:TemplatePar", say, false, TemplatePar.framing ) end end if not r then r = Local.L10nDef.en[ say ] end else m:inLanguage( c ) r = m:plain end if not r then r = string.format( "(((%s)))", say ) end return r end -- factory local function faculty( accept, attempt ) -- Check string as possible boolean -- Precondition: -- accept -- string; requirement -- boolean -- boolean+ -- attempt -- string; to be tested -- Postcondition: -- Return error keyword, or false -- Uses: -- Module:TemplUtl -- Foreign -- TemplUtl.faculty local r r = mw.text.trim( attempt ):lower if r "" then if accept "boolean+" then r = "empty" else r = false end elseif Local.boolean[ r ] or r:match( "^[01%-]+$" ) then r = false else local TemplUtl = Foreign( "TemplUtl" ) if TemplUtl and type( TemplUtl.faculty ) "function" then r TemplUtl.faculty( r, "-" ) if r "-" then r = "invalid" else r = false end else r = "invalid" end end return r end -- faculty local function failure( spec, suspect, options ) -- Submit localized error message -- Precondition: -- spec -- string; message ID -- suspect -- string or nil; additional information -- options -- table or nil; optional details -- options.template -- Postcondition: -- Return string -- Uses: -- factory local r = factory( spec ) if type( options ) "table" then if type( options.template ) "string" then if #options.template > 0 then r = string.format( "%s (%s)", r, options.template ) end end end if suspect then r = string.format( "%s: %s", r, suspect ) end return r end -- failure local function fair( story, scan ) -- Test for match (possibly user-defined with syntax error) -- Precondition: -- story -- string; parameter value -- scan -- string; pattern -- Postcondition: -- Return nil, if not matching, else non-nil -- Uses: -- mw.ustring.match return mw.ustring.match( story, scan ) end -- fair local function familiar( accept, attempt ) -- Check string as possible language name or list -- Precondition: -- accept -- string; requirement -- lang -- langs -- langW -- langsW -- lang+ -- langs+ -- langW+ -- langsW+ -- attempt -- string; to be tested -- Postcondition: -- Return error keyword, or false -- Uses: -- Module:Multilingual -- Foreign -- Multilingual.isLang local r if attempt and attempt ~= "" then local MultiL = Foreign( "Multilingual" ) if MultiL and type( MultiL.isLang ) == "function" then local lazy = accept:find( "W", 1, true ) if accept:find( "s", 1, true ) then local group = mw.text.split( attempt, "%s+" ) r = false for i = 1, #group do if not MultiL.isLang( group[ i ], lazy ) then r = "invalid" break -- for i end end -- for i elseif MultiL.isLang( attempt, lazy ) then r = false else r = "invalid" end else r = "missing" end elseif accept:find( "+", 1, true ) then r = "empty" else r = false end return r end -- familiar local function far( accept, attempt ) -- Check string as possible URL -- Precondition: -- accept -- string; requirement -- url -- url+ -- attempt -- string; to be tested -- Postcondition: -- Return error keyword, or false -- Uses: -- Module:URLutil -- Foreign -- URLutil.isWebURL local r if attempt and attempt ~= "" then local URLutil = Foreign( "URLutil" ) if URLutil and type( URLutil.isWebURL ) == "function" then if URLutil.isWebURL( attempt ) then r = false else r = "invalid" end else r = "missing" end elseif accept:find( "+", 1, true ) then r = "empty" else r = false end return r end -- far local function fast( accept, attempt ) -- Check string as possible date or time -- Precondition: -- accept -- string; requirement -- datetime -- datetime+ -- datetime/y -- datetime/y+ -- datetime/ym -- datetime/ym+ -- datetime/ymd -- datetime/ymd+ -- attempt -- string; to be tested -- Postcondition: -- Return error keyword, or false -- Uses: -- Module:DateTime -- Foreign -- DateTime.DateTime local r r = mw.text.trim( attempt ) if r "" then if accept:find( "+", 1, true ) then r "empty" else r false end else local DateTime Foreign( "DateTime" ) if type( DateTime ) "table" then local d = DateTime( attempt ) if type( d ) "table" then if accept:find( "/", 1, true ) then r "invalid" if accept:sub( 1, 10 ) "datetime/y" then if d.year then r = false if accept:sub( 1, 11 ) "datetime/ym" then if d.month then if accept:sub( 1, 12 ) "datetime/ymd" then if not d.dom then r = "invalid" end end else r = "invalid" end end end end else r = false end else r = "invalid" end else r = "invalid" end end return r end -- fast local function fault( store, key ) -- Add key to collection string and insert separator -- Precondition: -- store -- string or nil or false; collection string -- key -- string or number; to be appended -- Postcondition: -- Return string; extended local r local s if type( key ) == "number" then s = tostring( key ) else s = key end if store then r = string.format( "%s; %s", store, s ) else r = s end return r end -- fault local function feasible( analyze, options, abbr ) -- Check content of a value -- Precondition: -- analyze -- string to be analyzed -- options -- table or nil; optional details -- options.pattern -- options.key -- options.say -- abbr -- true: abbreviated error message -- Postcondition: -- Return string with error message as configured; -- false if valid or no answer permitted -- Uses: -- > Local.patterns -- failure -- mw.text.trim -- faculty -- fast -- facility -- familiar -- far -- fair -- containsCJK local r = false local s = false local show = nil local scan = false local stuff = mw.text.trim( analyze ) if type( options.pattern ) "string" then if options.key then r failure( "dupRule", false, options ) else scan options.pattern end else if type( options.key ) "string" then s = mw.text.trim( options.key ) else s = "+" end if s ~= "*" then scan = Local.patterns[ s ] end if type( scan ) "string" then if s "n" or s "0,0" or s "0.0" then if not stuff:match( "[0-9]" ) and not stuff:match( "^%s*$" ) then scan = false if options.say then show = string.format( ""%s"", options.say ) end if abbr then r = show else r = failure( "invalid", show, options ) end end end elseif s ~= "*" then local op, n, plus = s:match( "([<!=>]=?)([-0-9][%S]*)(+?)" ) if op then n = tonumber( n ) if n then local i = tonumber( stuff ) if i then if op "<" then i ( i < n ) elseif op "<=" then i = ( i <= n ) elseif op ">" then i ( i > n ) elseif op ">=" then i = ( i >= n ) elseif op " " then i = ( i n ) elseif op "!=" then i = ( i ~= n ) else n = false end end if not i then r = "invalid" end elseif plus then r = "undefined" end elseif s:match( "^boolean%+?$" ) then r = faculty( s, stuff ) n = true elseif s:match( "^datetime/?y?m?d?%+?$" ) then r = fast( s, stuff ) n = true elseif s:match( "^image%+?:?$" ) or s:match( "^file%+?:?$" ) then r = facility( s, stuff ) n = true elseif s:match( "langs?W?%+?" ) then r = familiar( s, stuff ) n = true elseif s:match( "url%+?" ) then r = far( s, stuff ) n = true end -- datetime+ -- iso8631+ -- line+ if not n and not r then r = "unknownRule" end if r then if options.say then show = string.format( ""%s" %s", options.say, s ) else show = s end if abbr then r = show else r = failure( r, show, options ) end end end end if scan then local legal, got = pcall( fair, stuff, scan ) if legal then if not got then if s == "aa" then got = containsCJK( stuff ) end if not got then if options.say then show = string.format( ""%s"", options.say ) end if abbr then r = show else r = failure( "invalid", show, options ) end end end else r = failure( "badPattern", string.format( "%s *** %s", scan, got ), options ) end end return r end -- feasible local function fed( haystack, needle ) -- Find needle in haystack map -- Precondition: -- haystack -- table; map of key values -- needle -- any; identifier -- Postcondition: -- Return true iff found local k, v, r for k, v in pairs( haystack ) do if k == needle then r = true end end -- for k, v return r or false end -- fed local function fetch( light, options ) -- Return regular table with all parameters -- Precondition: -- light -- true: template transclusion; false: #invoke -- options -- table; optional details -- options.low -- Postcondition: -- Return table; whitespace-only values as false -- Uses: -- TemplatePar.downcase -- TemplatePar.framing -- frame:getParent local g, k, v local r = { } if options.low then g = TemplatePar.downcase( options ) else g = TemplatePar.framing if light then g = g:getParent end g = g.args end if type( g ) "table" then r { } for k, v in pairs( g ) do if type( v ) "string" then if v:match( "^%s*$" ) then v = false end else v = false end if type( k ) == "number" then k = tostring( k ) end r[ k ] = v end -- for k, v else r = g end return r end -- fetch local function figure( append, options ) -- Extend options by rule from #invoke strings -- Precondition: -- append -- string or nil; requested rule -- options -- table; details -- ++ .key -- ++ .pattern -- Postcondition: -- Return sequence table local r = options if type( append ) "string" then local story mw.text.trim( append ) local sub story:match( "^/(.*%S)/$" ) if type( sub ) "string" then sub = sub:gsub( "%%!", "|" ) :gsub( "%%%(%(", "" ) :gsub( "\\n", string.char( 10 ) ) options.pattern = sub options.key = nil else options.key = story options.pattern = nil end end return r end -- figure local function fill( specified ) -- Split requirement string separated by '=' -- Precondition: -- specified -- string or nil; requested parameter set -- Postcondition: -- Return sequence table -- Uses: -- mw.text.split local r if specified then local i, s r = mw.text.split( specified, "%s*=%s*" ) for i = #r, 1, -1 do s = r[ i ] if #s == 0 then table.remove( r, i ) end end -- for i, -1 else r = { } end return r end -- fill local function finalize( submit, options ) -- Finalize message -- Precondition: -- submit -- string or false or nil; non-empty error message -- options -- table or nil; optional details -- options.format -- options.preview -- options.cat -- options.template -- Postcondition: -- Return string or false -- Uses: -- TemplatePar.framing -- factory local r = false if submit then local lazy = false local learn = false local show = false local opt, s if type( options ) "table" then opt options show opt.format lazy ( show "" or show "0" or show "-" ) s = opt.preview if type( s ) "string" and s ~ "" and s ~ "0" and s ~ "-" then local sniffer "" if lazy then show "" lazy false end if TemplatePar.framing:preprocess( sniffer ) "" then if s "1" then show "*" else show s end learn true end end else opt { } end if lazy then if not opt.cat then r string.format( "%s %s", submit, factory( "noMSGnoCAT" ) ) end else r submit end if r and not lazy then local i if not show or show "*" then local e = mw.html.create( "span" ) :attr( "class", "error" ) :wikitext( "@@@" ) if learn then local max = 1000000000 local id = math.floor( os.clock * max ) local sign = string.format( "error_%d", id ) local btn = mw.html.create( "span" ) local top = mw.html.create( "div" ) e:attr( "id", sign ) btn:css( { ["background"] = "#FFFF00", ["border"] = "#FF0000 3px solid", ["font-weight"] = "bold", ["padding"] = "2px", ["text-decoration"] = "none" } ) :wikitext( ">>>" ) sign = string.format( "%s", sign, tostring( btn ) ) top:wikitext( sign, "&#160;", submit ) mw.addWarning( tostring( top ) ) end show = tostring( e ) end i = show:find( "@@@", 1, true ) if i then -- No gsub since r might contain "%3" (e.g. URL) r = string.format( "%s%s%s", show:sub( 1, i - 1 ), r, show:sub( i + 3 ) ) else r = show end end if learn and r then -- r = fatal( r ) end s = opt.cat if type( s ) "string" then local link if opt.errNS then local ns mw.title.getCurrentTitle.namespace local st type( opt.errNS ) if st "string" then local space = string.format( ".*%%s%d%%s.*", ns ) local spaces = string.format( " %s ", opt.errNS ) if spaces:match( space ) then link = true end elseif st "table" then for i 1, #opt.errNS do if opt.errNS[ i ] ns then link = true break -- for i end end -- for i end else link = true end if link then local cats, i if not r then r = "" end if s:find( "@@@" ) then if type( opt.template ) == "string" then s = s:gsub( "@@@", opt.template ) end end cats = mw.text.split( s, "%s*#%s*" ) for i = 1, #cats do s = mw.text.trim( cats[ i ] ) if #s > 0 then r = string.format( "%s", r, s ) end end -- for i end end end return r end -- finalize local function finder( haystack, needle ) -- Find needle in haystack sequence -- Precondition: -- haystack -- table; sequence of key names, downcased if low -- needle -- any; key name -- Postcondition: -- Return true iff found local i for i = 1, #haystack do if haystack[ i ] == needle then return true end end -- for i return false end -- finder local function fix( valid, duty, got, options ) -- Perform parameter analysis -- Precondition: -- valid -- table; unique sequence of known parameters -- duty -- table; sequence of mandatory parameters -- got -- table; sequence of current parameters -- options -- table or nil; optional details -- Postcondition: -- Return string as configured; empty if valid -- Uses: -- finder -- fault -- failure -- fed local r = false local lack for k, v in pairs( got ) do if k == "" then lack = true break -- for k, v elseif not finder( valid, k ) then r = fault( r, k ) end end -- for k, v if lack then r = failure( "unavailable", false, options ) elseif r then r = failure( "unknown", string.format( ""%s"", r ), options ) else -- all names valid local i, s for i = 1, #duty do s = duty[ i ] if not fed( got, s ) then r = fault( r, s ) end end -- for i if r then r = failure( "undefined", r, options ) else -- all mandatory present for i = 1, #duty do s = duty[ i ] if not got[ s ] then r = fault( r, s ) end end -- for i if r then r = failure( "empty", r, options ) end end end return r end -- fix local function flat( collection, options ) -- Return all table elements with downcased string -- Precondition: -- collection -- table; k=v pairs -- options -- table or nil; optional messaging details -- Postcondition: -- Return table, may be empty; or string with error message. -- Uses: -- mw.ustring.lower -- fault -- failure local k, v local r = { } local e = false for k, v in pairs( collection ) do if type ( k ) == "string" then k = mw.ustring.lower( k ) if r[ k ] then e = fault( e, k ) end end r[ k ] = v end -- for k, v if e then r = failure( "multiSpell", e, options ) end return r end -- flat local function fold( options ) -- Merge two tables, create new sequence if both not empty -- Precondition: -- options -- table; details -- options.mandatory sequence to keep unchanged -- options.optional sequence to be appended -- options.low downcased expected -- Postcondition: -- Return merged table, or message string if error -- Uses: -- finder -- fault -- failure -- flat local i, e, r, s local base = options.mandatory local extend = options.optional if #base 0 then if #extend 0 then r = { } else r = extend end else if #extend 0 then r base else e false for i 1, #extend do s extend[ i ] if finder( base, s ) then e fault( e, s ) end end -- for i if e then r failure( "dupOpt", e, options ) else r { } for i 1, #base do table.insert( r, base[ i ] ) end -- for i for i 1, #extend do table.insert( r, extend[ i ] ) end -- for i end end end if options.low and type( r ) "table" then r = flat( r, options ) end return r end -- fold local function form( light, options, frame ) -- Run parameter analysis on current environment -- Precondition: -- light -- true: template transclusion; false: #invoke -- options -- table or nil; optional details -- options.mandatory -- options.optional -- frame -- object; #invoke environment, or false -- Postcondition: -- Return string with error message as configured; -- false if valid -- Uses: -- TemplatePar.framing -- fold -- fetch -- fix -- finalize local duty, r if frame then TemplatePar.framing( frame ) end if type( options ) "table" then if type( options.mandatory ) ~ "table" then options.mandatory { } end duty options.mandatory if type( options.optional ) ~ "table" then options.optional { } end r fold( options ) else options { } duty { } r { } end if type( r ) "table" then local got = fetch( light, options ) if type( got ) == "table" then r = fix( r, duty, got, options ) else r = got end end return finalize( r, options ) end -- form local function format( analyze, options ) -- Check validity of a value -- Precondition: -- analyze -- string to be analyzed -- options -- table or nil; optional details -- options.say -- options.min -- options.max -- Postcondition: -- Return string with error message as configured; -- false if valid or no answer permitted -- Uses: -- feasible -- failure local r = feasible( analyze, options, false ) local show if options.min and not r then if type( options.min ) "number" then if type( options.max ) "number" then if options.max < options.min then r = failure( "minmax", string.format( "%d > %d", options.min, options.max ), options ) end end if #analyze < options.min and not r then show = " <" .. options.min if options.say then show = string.format( "%s "%s"", show, options.say ) end r = failure( "tooShort", show, options ) end else r = failure( "invalidPar", "min", options ) end end if options.max and not r then if type( options.max ) == "number" then if #analyze > options.max then show = " >" .. options.max if options.say then show = string.format( "%s "%s"", show, options.say ) end r = failure( "tooLong", show, options ) end else r = failure( "invalidPar", "max", options ) end end return r end -- format local function formatted( assignment, access, options ) -- Check validity of one particular parameter in a collection -- Precondition: -- assignment -- collection -- access -- id of parameter in collection -- options -- table or nil; optional details -- Postcondition: -- Return string with error message as configured; -- false if valid or no answer permitted -- Uses: -- mw.text.trim -- format -- failure local r = false if type( assignment ) "table" then local story assignment.args[ access ] or "" if type( access ) "number" then story = mw.text.trim( story ) end if type( options ) ~= "table" then options = { } end options.say = access r = format( story, options ) end return r end -- formatted local function furnish( frame, action ) -- Prepare #invoke evaluation of .assert or .valid -- Precondition: -- frame -- object; #invoke environment -- action -- "assert" or "valid" -- Postcondition: -- Return string with error message or "" -- Uses: -- form -- failure -- finalize -- TemplatePar.valid -- TemplatePar.assert local options = { mandatory = { "1" }, optional = { "2", "cat", "errNS", "low", "max", "min", "format", "preview", "template" }, template = string.format( "&#35;invoke:%s|%s|", "TemplatePar", action ) } local r = form( false, options, frame ) if not r then local s options = { cat = frame.args.cat, errNS = frame.args.errNS, low = frame.args.low, format = frame.args.format, preview = frame.args.preview, template = frame.args.template } options = figure( frame.args[ 2 ], options ) if type( frame.args.min ) "string" then s frame.args.min:match( "^%s*([0-9]+)%s*$" ) if s then options.min tonumber( s ) else r failure( "invalidPar", "min " .. frame.args.min, options ) end end if type( frame.args.max ) "string" then s = frame.args.max:match( "^%s*([1-9][0-9]*)%s*$" ) if s then options.max = tonumber( s ) else r = failure( "invalidPar", "max=" .. frame.args.max, options ) end end if r then r = finalize( r, options ) else s = frame.args[ 1 ] or "" r = tonumber( s ) if ( r ) then s = r end if action "valid" then r TemplatePar.valid( s, options ) elseif action "assert" then r = TemplatePar.assert( s, "", options ) end end end return r or "" end -- furnish TemplatePar.assert = function ( analyze, append, options ) -- Perform parameter analysis on a single string -- Precondition: -- analyze -- string to be analyzed -- append -- string: append error message, prepending -- false or nil: throw error with message -- options -- table; optional details -- Postcondition: -- Return string with error message as configured; -- false if valid -- Uses: -- format local r = format( analyze, options ) if ( r ) then if ( type( append ) == "string" ) then if ( append ~= "" ) then r = string.format( "%s %s", append, r ) end else error( r, 0 ) end end return r end -- TemplatePar.assert TemplatePar.check = function ( options ) -- Run parameter analysis on current template environment -- Precondition: -- options -- table or nil; optional details -- options.mandatory -- options.optional -- Postcondition: -- Return string with error message as configured; -- false if valid -- Uses: -- form return form( true, options, false ) end -- TemplatePar.check TemplatePar.count = function -- Return number of template parameters -- Postcondition: -- Return number, starting at 0 -- Uses: -- mw.getCurrentFrame -- frame:getParent local k, v local r = 0 local t = mw.getCurrentFrame:getParent local o = t.args for k, v in pairs( o ) do r = r + 1 end -- for k, v return r end -- TemplatePar.count TemplatePar.countNotEmpty = function -- Return number of template parameters with more than whitespace -- Postcondition: -- Return number, starting at 0 -- Uses: -- mw.getCurrentFrame -- frame:getParent local k, v local r = 0 local t = mw.getCurrentFrame:getParent local o = t.args for k, v in pairs( o ) do if not v:match( "^%s*$" ) then r = r + 1 end end -- for k, v return r end -- TemplatePar.countNotEmpty TemplatePar.downcase = function ( options ) -- Return all template parameters with downcased name -- Precondition: -- options -- table or nil; optional messaging details -- Postcondition: -- Return table, may be empty; or string with error message. -- Uses: -- mw.getCurrentFrame -- frame:getParent -- flat local t = mw.getCurrentFrame:getParent return flat( t.args, options ) end -- TemplatePar.downcase TemplatePar.valid = function ( access, options ) -- Check validity of one particular template parameter -- Precondition: -- access -- id of parameter in template transclusion -- string or number -- options -- table or nil; optional details -- Postcondition: -- Return string with error message as configured; -- false if valid or no answer permitted -- Uses: -- mw.text.trim -- TemplatePar.downcase -- TemplatePar.framing -- frame:getParent -- formatted -- failure -- finalize local r = type( access ) if r "string" then r mw.text.trim( access ) if #r 0 then r = false end elseif r == "number" then r = access else r = false end if r then local params if type( options ) ~= "table" then options = { } end if options.low then params = TemplatePar.downcase( options ) else params = TemplatePar.framing:getParent end r = formatted( params, access, options ) else r = failure( "noname", false, options ) end return finalize( r, options ) end -- TemplatePar.valid TemplatePar.verify = function ( options ) -- Perform #invoke parameter analysis -- Precondition: -- options -- table or nil; optional details -- Postcondition: -- Return string with error message as configured; -- false if valid -- Uses: -- form return form( false, options, false ) end -- TemplatePar.verify TemplatePar.framing = function( frame ) -- Ensure availability of frame object -- Precondition: -- frame -- object; #invoke environment, or false -- Postcondition: -- Return frame object -- Uses: -- >< Local.frame if not Local.frame then if type( frame ) "table" and type( frame.args ) "table" and type( frame.getParent ) "function" and type( frame:getParent ) "table" and type( frame:getParent.getParent ) "function" and type( frame:getParent:getParent ) "nil" then Local.frame = frame else Local.frame = mw.getCurrentFrame end end return Local.frame end -- TemplatePar.framing Failsafe.failsafe = function ( atleast ) -- Retrieve versioning and check for compliance -- Precondition: -- atleast -- string, with required version -- or wikidata|item|~|@ or false -- Postcondition: -- Returns string -- with queried version/item, also if problem -- false -- if appropriate -- 2020-08-17 local since = atleast local last = ( since "~" ) local linked ( since "@" ) local link = ( since "item" ) local r if last or link or linked or since "wikidata" then local item = Failsafe.item since = false if type( item ) "number" and item > 0 then local suited string.format( "Q%d", item ) if link then r suited else local entity mw.wikibase.getEntity( suited ) if type( entity ) "table" then local seek = Failsafe.serialProperty or "P348" local vsn = entity:formatPropertyValues( seek ) if type( vsn ) "table" and type( vsn.value ) "string" and vsn.value ~= "" then if last and vsn.value Failsafe.serial then r false elseif linked then if mw.title.getCurrentTitle.prefixedText mw.wikibase.getSitelink( suited ) then r = false else r = suited end else r = vsn.value end end end end end end if type( r ) == "nil" then if not since or since <= Failsafe.serial then r = Failsafe.serial else r = false end end return r end -- Failsafe.failsafe -- Provide external access local p = {} function p.assert( frame ) -- Perform parameter analysis on some single string -- Precondition: -- frame -- object; #invoke environment -- Postcondition: -- Return string with error message or "" -- Uses: -- furnish return furnish( frame, "assert" ) end -- p.assert function p.check( frame ) -- Check validity of template parameters -- Precondition: -- frame -- object; #invoke environment -- Postcondition: -- Return string with error message or "" -- Uses: -- form -- fill local options = { optional = { "all", "opt", "cat", "errNS", "low", "format", "preview", "template" }, template = "&#35;invoke:TemplatePar|check|" } local r = form( false, options, frame ) if not r then options = { mandatory = fill( frame.args.all ), optional = fill( frame.args.opt ), cat = frame.args.cat, errNS = frame.args.errNS, low = frame.args.low, format = frame.args.format, preview = frame.args.preview, template = frame.args.template } r = form( true, options, frame ) end return r or "" end -- p.check function p.count( frame ) -- Count number of template parameters -- Postcondition: -- Return string with digits including "0" -- Uses: -- TemplatePar.count return tostring( TemplatePar.count ) end -- p.count function p.countNotEmpty( frame ) -- Count number of template parameters which are not empty -- Postcondition: -- Return string with digits including "0" -- Uses: -- TemplatePar.countNotEmpty return tostring( TemplatePar.countNotEmpty ) end -- p.countNotEmpty function p.match( frame ) -- Combined analysis of parameters and their values -- Precondition: -- frame -- object; #invoke environment -- Postcondition: -- Return string with error message or "" -- Uses: -- TemplatePar.framing -- mw.text.trim -- mw.ustring.lower -- failure -- form -- TemplatePar.downcase -- figure -- feasible -- fault -- finalize local r = false local options = { cat = frame.args.cat, errNS = frame.args.errNS, low = frame.args.low, format = frame.args.format, preview = frame.args.preview, template = frame.args.template } local k, v, s local params = { } TemplatePar.framing( frame ) for k, v in pairs( frame.args ) do if type( k ) "number" then s, v v:match( "^ *([^ ]+) * *(%S.*%S*) *$" ) if s then s mw.text.trim( s ) if s "" then s = false end end if s then if options.low then s = mw.ustring.lower( s ) end if params[ s ] then s = params[ s ] s[ #s + 1 ] = v else params[ s ] = { v } end else r = failure( "invalidPar", tostring( k ), options ) break -- for k, v end end end -- for k, v if not r then s = { } for k, v in pairs( params ) do s[ #s + 1 ] = k end -- for k, v options.optional = s r = form( true, options, frame ) end if not r then local errMiss, errValues, lack, rule local targs = frame:getParent.args options.optional = nil if options.low then targs = TemplatePar.downcase else targs = frame:getParent.args end errMiss = false errValues = false for k, v in pairs( params ) do options.say = k s = targs[ k ] if s then if s == "" then lack = true else lack = false end else s = "" lack = true end for r, rule in pairs( v ) do options = figure( rule, options ) r = feasible( s, options, true ) if r then if lack then if errMiss then s = "%s, "%s"" errMiss = string.format( s, errMiss, k ) else errMiss = string.format( ""%s"", k ) end elseif not errMiss then errValues = fault( errValues, r ) end break -- for r, rule end end -- for s, rule end -- for k, v r = ( errMiss or errValues ) if r then if errMiss then r = failure( "undefined", errMiss, options ) else r = failure( "invalid", errValues, options ) end r = finalize( r, options ) end end return r or "" end -- p.match function p.valid( frame ) -- Check validity of one particular template parameter -- Precondition: -- frame -- object; #invoke environment -- Postcondition: -- Return string with error message or "" -- Uses: -- furnish return furnish( frame, "valid" ) end -- p.valid 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 Failsafe.failsafe( since ) or "" end -- p.failsafe function p.TemplatePar -- Retrieve function access for modules -- Postcondition: -- Return table with functions return TemplatePar end -- p.TemplatePar setmetatable( p, { __call = function ( func, ... ) setmetatable( p, nil ) return Failsafe end } ) return p
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Izgara yada normal mod

Temanızda forum listeleme yapısını ızgara yapısında yada normal yapıda listemek için kullanabilirsiniz.

Forum arkaplan resimleri

Forum arkaplanlarına eklenmiş olan resimlerinin kontrolü senin elinde, resimleri aç/kapat

Sidebar blogunu kapat/aç

Forumun kalabalığında kurtulmak için sidebar (kenar çubuğunu) açıp/kapatarak gereksiz kalabalıklardan kurtula bilirsiniz.

Yapışkan sidebar kapat/aç

Yapışkan sidebar ile sidebar alanını daha hızlı ve verimli kullanabilirsiniz.

Radius aç/kapat

Blok köşelerinde bulunan kıvrımları kapat/aç bu şekilde tarzını yansıt.

Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Geri