Module:Arguments
- Afrikaans
- العربية
- Azərbaycanca
- Башҡортса
- Беларуская
- Български
- বাংলা
- Català
- Čeština
- Cymraeg
- Ελληνικά
- Español
- Euskara
- فارسی
- Suomi
- Français
- עברית
- हिन्दी
- Hrvatski
- Magyar
- Interlingua
- Bahasa Indonesia
- Íslenska
- Italiano
- 日本語
- Қазақша
- 한국어
- Latina
- Lietuvių
- Македонски
- മലയാളം
- मराठी
- Bahasa Melayu
- नेपाली
- Norsk bokmål
- ਪੰਜਾਬੀ
- Polski
- Português
- Русский
- တႆး
- සිංහල
- Српски / srpski
- తెలుగు
- ไทย
- Tagalog
- Türkçe
- Татарча / tatarça
- Українська
- Tiếng Việt
- 中文
Appearance
From Wikibooks, open books for an open world
This module provides easy processing of arguments passed from #invoke. It is a meta-module, meant for use by other modules, and should not be called from #invoke directly. Its features are:
- Easy trimming of arguments and removal of blank arguments.
- Arguments can be passed by both the current frame and by the parent frame at the same time.
- Arguments can be passed in directly from another Lua module or from the debug console. Most features can be customized.
The above documentation is transcluded from Module:Arguments/doc. (edit | history)
Editors can experiment in this module's sandbox (create | mirror) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module's sandbox (create | mirror) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
-- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. locallibraryUtil=require('libraryUtil') localcheckType=libraryUtil.checkType localarguments={} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. localfunctiontidyValDefault(key,val) iftype(val)=='string'then val=val:match('^%s*(.-)%s*$') ifval==''then returnnil else returnval end else returnval end end localfunctiontidyValTrimOnly(key,val) iftype(val)=='string'then returnval:match('^%s*(.-)%s*$') else returnval end end localfunctiontidyValRemoveBlanksOnly(key,val) iftype(val)=='string'then ifval:find('%S')then returnval else returnnil end else returnval end end localfunctiontidyValNoChange(key,val) returnval end localfunctionmatchesTitle(given,title) localtp=type(given) return(tp=='string'ortp=='number')andmw.title.new(given).prefixedText==title end localtranslate_mt={__index=function(t,k)returnkend} functionarguments.getArgs(frame,options) checkType('getArgs',1,frame,'table',true) checkType('getArgs',2,options,'table',true) frame=frameor{} options=optionsor{} --[[ -- Set up argument translation. --]] options.translate=options.translateor{} ifgetmetatable(options.translate)==nilthen setmetatable(options.translate,translate_mt) end ifoptions.backtranslate==nilthen options.backtranslate={} fork,vinpairs(options.translate)do options.backtranslate[v]=k end end ifoptions.backtranslateandgetmetatable(options.backtranslate)==nilthen setmetatable(options.backtranslate,{ __index=function(t,k) ifoptions.translate[k]~=kthen returnnil else returnk end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] localfargs,pargs,luaArgs iftype(frame.args)=='table'andtype(frame.getParent)=='function'then ifoptions.wrappersthen --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] localparent=frame:getParent() ifnotparentthen fargs=frame.args else localtitle=parent:getTitle():gsub('/sandbox$','') localfound=false ifmatchesTitle(options.wrappers,title)then found=true elseiftype(options.wrappers)=='table'then for_,vinpairs(options.wrappers)do ifmatchesTitle(v,title)then found=true break end end end -- We test for false specifically here so that nil (the default) acts like true. iffoundoroptions.frameOnly==falsethen pargs=parent.args end ifnotfoundoroptions.parentOnly==falsethen fargs=frame.args end end else -- options.wrapper isn't set, so check the other options. ifnotoptions.parentOnlythen fargs=frame.args end ifnotoptions.frameOnlythen localparent=frame:getParent() pargs=parentandparent.argsornil end end ifoptions.parentFirstthen fargs,pargs=pargs,fargs end else luaArgs=frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. localargTables={fargs} argTables[#argTables+1]=pargs argTables[#argTables+1]=luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] localtidyVal=options.valueFunc iftidyValthen iftype(tidyVal)~='function'then error( "bad value assigned to option 'valueFunc'" ..'(function expected, got ' ..type(tidyVal) ..')', 2 ) end elseifoptions.trim~=falsethen ifoptions.removeBlanks~=falsethen tidyVal=tidyValDefault else tidyVal=tidyValTrimOnly end else ifoptions.removeBlanks~=falsethen tidyVal=tidyValRemoveBlanksOnly else tidyVal=tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] localargs,metaArgs,nilArgs,metatable={},{},{},{} setmetatable(args,metatable) localfunctionmergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for_,tinipairs(tables)do forkey,valinpairs(t)do ifmetaArgs[key]==nilandnilArgs[key]~='h'then localtidiedVal=tidyVal(key,val) iftidiedVal==nilthen nilArgs[key]='s' else metaArgs[key]=tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index=function(t,key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] iftype(key)=='string'then key=options.translate[key] end localval=metaArgs[key] ifval~=nilthen returnval elseifmetatable.donePairsornilArgs[key]then returnnil end for_,argTableinipairs(argTables)do localargTableVal=tidyVal(key,argTable[key]) ifargTableVal~=nilthen metaArgs[key]=argTableVal returnargTableVal end end nilArgs[key]='h' returnnil end metatable.__newindex=function(t,key,val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. iftype(key)=='string'then key=options.translate[key] end ifoptions.readOnlythen error( 'could not write to argument table key "' ..tostring(key) ..'"; the table is read-only', 2 ) elseifoptions.noOverwriteandargs[key]~=nilthen error( 'could not write to argument table key "' ..tostring(key) ..'"; overwriting existing arguments is not permitted', 2 ) elseifval==nilthen --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key]=nil nilArgs[key]='h' else metaArgs[key]=val end end localfunctiontranslatenext(invariant) localk,v=next(invariant.t,invariant.k) invariant.k=k ifk==nilthen returnnil elseiftype(k)~='string'ornotoptions.backtranslatethen returnk,v else localbacktranslate=options.backtranslate[k] ifbacktranslate==nilthen -- Skip this one. This is a tail call, so this won't cause stack overflow returntranslatenext(invariant) else returnbacktranslate,v end end end metatable.__pairs=function() -- Called when pairs is run on the args table. ifnotmetatable.donePairsthen mergeArgs(argTables) metatable.donePairs=true end returntranslatenext,{t=metaArgs} end localfunctioninext(t,i) -- This uses our __index metamethod localv=t[i+1] ifv~=nilthen returni+1,v end end metatable.__ipairs=function(t) -- Called when ipairs is run on the args table. returninext,t,0 end returnargs end returnarguments