Module:Val
- Аԥсшәа
- العربية
- অসমীয়া
- Azərbaycanca
- تۆرکجه
- Basa Bali
- বাংলা
- Беларуская (тарашкевіца)
- भोजपुरी
- Буряад
- Català
- Чӑвашла
- Čeština
- Chavacano de Zamboanga
- الدارجة
- Euskara
- فارسی
- Gaeilge
- Galego
- 한국어
- Hausa
- Հայերեն
- हिन्दी
- Ilokano
- Bahasa Indonesia
- Italiano
- עברית
- Jawa
- ქართული
- Latina
- Lietuvių
- Ligure
- मैथिली
- Македонски
- മലയാളം
- ဘာသာမန်
- 閩東語 / Mìng-dĕ̤ng-ngṳ̄
- Мокшень
- Монгол
- မြန်မာဘာသာ
- Na Vosa Vakaviti
- नेपाली
- 日本語
- Oʻzbekcha / ўзбекча
- ပအိုဝ်ႏဘာႏသာႏ
- Português
- Română
- Scots
- Shqip
- Simple English
- Slovenščina
- کوردی
- Српски / srpski
- Suomi
- Svenska
- தமிழ்
- Taqbaylit
- တႆး
- Tetun
- ไทย
- Türkçe
- Українська
- اردو
- Vèneto
- Tiếng Việt
- 粵語
- 中文
- Kumoring
Appearance
From Wikipedia, the free encyclopedia
Warning This Lua module is used on approximately 43,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them.
This module depends on the following other modules:
This module implements {{Val }}.
The following modules are developed:
- Module:Val • Main module.
- Module:Val/units • Definitions for units built-in to val.
Use {{val/sandbox }} for testing, for example:
{{val/sandbox|1234.5678|(23)|u=cm}}→ 1234.5678(23) cm{{val/sandbox|1234.5678|1.23|u=cm}}→ 1234.5678±1.23 cm{{val/sandbox|1234.5678|1.23|4.56|u=cm}}→ 1234.5678+1.23
−4.56 cm{{val/sandbox|1234.5678|e=3|u=cm}}→ 1234.5678×ばつ103 cm{{val/sandbox|1234.5678|(23)|e=3|u=cm}}→ 1234.5678(23)×ばつ103 cm{{val/sandbox|1234.5678|1.23|e=3|u=cm}}→ (1234.5678±1.23)×ばつ103 cm{{val/sandbox|1234.5678|1.23|4.56|e=3|u=cm}}→ 1234.5678+1.23
−4.56×ばつ103 cm{{val/sandbox|1234.5678|1.23|4.56|e=3|u=cm|end=$|+errend=U$|-errend=L$}}→ 1234.5678$+1.23U$
−4.56L$×ばつ103 cm{{val/sandbox|1234.5678|(23)|u=deg}}→ 1234.5678(23)°{{val/sandbox|1234.5678|1.23|u=deg}}→ 1234.5678°±1.23°{{val/sandbox|1234.5678|1.23|4.56|u=deg}}→ 1234.5678°+1.23°
−4.56°{{val/sandbox|1234.5678|e=3|u=deg}}→ 1234.5678°×ばつ103{{val/sandbox|1234.5678|(23)|e=3|u=deg}}→ 1234.5678(23)°×ばつ103{{val/sandbox|1234.5678|1.23|e=3|u=deg}}→ (1234.5678°±1.23°)×ばつ103{{val/sandbox|1234.5678|1.23|4.56|e=3|u=deg}}→ 1234.5678°+1.23°
−4.56°×ばつ103{{val/sandbox|1234.5678|1.23|4.56|e=3|u=deg|end=$|+errend=U$|-errend=L$}}→ 1234.5678$°+1.23U$°
−4.56L$°×ばつ103
The above documentation is transcluded from Module:Val/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Subpages of this module.
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Subpages of this module.
-- For Template:Val, output a number and optional unit. -- Format options include scientific and uncertainty notations. localnumdot='.'-- decimal mark (use ',' for Italian) localnumsep=','-- group separator (use ' ' for Italian) localmtext={ -- Message and other text that should be localized. ['mt-bad-exponent']='exponent parameter (<b>e</b>)', ['mt-parameter']='parameter ', ['mt-not-number']='is not a valid number', ['mt-cannot-range']='cannot use a range if the first parameter includes "e"', ['mt-need-range']='needs a range in parameter 2', ['mt-should-range']='should be a range', ['mt-cannot-with-e']='cannot be used if the first parameter includes "e"', ['mt-not-range']='does not accept a range', ['mt-cannot-e']='cannot use e notation', ['mt-too-many-parameter']='too many parameters', ['mt-need-number']='need a number after the last parameter because it is a range.', ['mt-ignore-parameter4']='Val parameter 4 ignored', ['mt-val-not-supported']='Val parameter "%s=%s" is not supported', ['mt-invalid-scale']='Unit "%s" has invalid scale "%s"', ['mt-both-u-ul']='unit (<b>u</b>) and unit with link (<b>ul</b>) are both specified, only one is allowed.', ['mt-both-up-upl']='unit per (<b>up</b>) and unit per with link (<b>upl</b>) are both specified, only one is allowed.', } localdata_module='Module:Val/units' localconvert_module='Module:Convert' localfunctionvalerror(msg,nocat,iswarning) -- Return formatted message text for an error or warning. -- Can append "#FormattingError" to URL of a page with a problem to find it. localanchor='<span id="FormattingError"></span>' localbody,category ifnocatormw.title.getCurrentTitle():inNamespaces(1,2,3,5)then -- No category in Talk, User, User_talk, or Wikipedia_talk. category='' else category='[[Category:Pages with incorrect formatting templates use]]' end iswarning=false-- problems are infrequent so try showing large error so editor will notice ifiswarningthen body='<sup class="noprint Inline-Template" style="white-space:nowrap;">'.. '[[Template:Val|<span title="'.. msg:gsub('"','"').. '">warning</span>]]</sup>' else body='<strong class="error">'.. 'Error in {{[[Template:val|val]]}}: '.. msg.. '</strong>' end returnanchor..body..category end localrange_types={ -- No need for ' ' because nowrap applies to all output. [","]=", ", ["by"]=" by ", ["-"]="–", ["–"]="–", ["and"]=" and ", ["or"]=" or ", ["to"]=" to ", ["x"]=" ×ばつ ", [×ばつ"]=" ×ばつ ", ["/"]="/", } localrange_repeat_unit={ -- WP:UNIT wants unit repeated when a "multiply" range is used. ["x"]=true, [×ばつ"]=true, } localfunctionextract_item(index,numbers,arg) -- Extract an item from arg and store the result in numbers[index]. -- If no argument or if argument is valid, return nil (no error); -- otherwise, return an error message. -- The stored result is: -- * a table for a number (empty if there was no specified number); or -- * a string for range text -- Input like 1e3 is regarded as invalid for all except argument 1 -- which accepts e notation as an alternative to the 'e' argument. -- Input group separators are removed. localwhich=index localfunctionfail(msg) localdescription ifwhich=='e'then description=mtext['mt-bad-exponent'] else description=mtext['mt-parameter']..which end returndescription..' '..(msgormtext['mt-not-number'])..'.' end localresult={} localrange=range_types[arg] ifrangethen iftype(index)=='number'and(index%2==0)then ifindex==2then ifnumbers[1]andnumbers[1].expthen returnfail(mtext['mt-cannot-range']) end numbers.has_ranges=true else ifnotnumbers.has_rangesthen returnfail(mtext['mt-need-range']) end end numbers[index]=range ifrange_repeat_unit[arg]then -- Any "repeat" range forces unit (if any) to be repeated for all items. numbers.isrepeat=true end returnnil end returnfail(mtext['mt-not-range']) end ifnumbers.has_rangesandtype(index)=='number'and(index%2==0)then returnfail(mtext['mt-should-range']) end ifindex=='e'then locale=numbers[1]andnumbers[1].exp ifethen ifargthen returnfail(mtext['mt-cannot-with-e']) end arg=e which=1 end end ifargandarg~=''then arg=arg:gsub(numsep,'') ifnumdot~='.'then arg=arg:gsub(numdot,'.') end ifarg:sub(1,1)=='('andarg:sub(-1)==')'then result.parens=true arg=arg:sub(2,-2) end locala,b=arg:match('^(.+)[Ee](.+)$') ifathen ifindex==1then arg=a result.exp=b else returnfail(mtext['mt-cannot-e']) end end localisnegative,propersign,prefix localminus='−' prefix,arg=arg:match('^(.-)([%d.]+)$') localvalue=tonumber(arg) ifnotvaluethen returnfail() end ifarg:sub(1,1)=='.'then arg='0'..arg end ifprefix==''then -- Ignore. elseifprefix=='±'then -- Display for first number, ignore for others. ifindex==1then propersign='±' end elseifprefix=='+'then propersign='+' elseifprefix=='-'orprefix==minusthen propersign=minus isnegative=true else returnfail() end result.clean=arg result.sign=propersignor'' result.value=isnegativeand-valueorvalue end numbers[index]=result returnnil-- no error end localfunctionget_args(numbers,args) -- Extract arguments and store the results in numbers. -- Return nothing (no error) if ok; otherwise, return an error message. forindex=1,99do localwhich=index localarg=args[which]-- has been trimmed ifnotargthen which='e' arg=args[which] end localmsg=extract_item(which,numbers,arg) ifmsgthen returnmsg end ifwhich=='e'then break end ifindex>19then returnmtext['mt-too-many-parameter'] end end ifnumbers.has_rangesand(#numbers%2==0)then returnmtext['mt-need-number'] end end localfunctionget_scale(text,ucode) -- Return the value of text as a number, or throw an error. -- This supports extremely basic expressions of the form: -- a / b -- a ^ b -- where a and b are numbers or 'pi'. localn=tonumber(text) ifnthen returnn end n=text:gsub('pi',math.pi) for_,opinipairs({'/','^'})do locala,b=n:match('^(.-)'..op..'(.*)$') ifathen a=tonumber(a) b=tonumber(b) ifaandbthen ifop=='/'then returna/b elseifop=='^'then returna^b end end break end end error(string.format(mtext['mt-invalid-scale'],ucode,text)) end localfunctionget_builtin_unit(ucode,definitions) -- Return table of information for the specified built-in unit, or nil if not known. -- Each defined unit code must be followed by two spaces (not tab characters). local_,pos=definitions:find('\n'..ucode..' ',1,true) ifposthen localendline=definitions:find('%s*\n',pos) ifendlinethen localresult={} localn=0 localtext=definitions:sub(pos+1,endline-1):gsub('%s%s+','\t') foritemin(text..'\t'):gmatch('(%S.-)\t')do ifitem=='ALIAS'then result.alias=true elseifitem=='ANGLE'then result.isangle=true result.nospace=true elseifitem=='NOSPACE'then result.nospace=true elseifitem=='SI'then result.si=true else n=n+1 ifn==1then locallink,symbol=item:match('^%[%[([^|]+)|(.+)%]%]$') iflinkthen result.symbol=symbol result.link=link n=2 else result.symbol=item end elseifn==2then result.link=item elseifn==3then result.scale_text=item result.scale=get_scale(item,ucode) else result.more_ignored=item break end end end ifresult.sithen locals=result.symbol ifucode=='mc'..sorucode=='mu'..sthen result.ucode='μ'..s-- unit code for convert should be this end end ifn>=2or(n>=1andresult.alias)then returnresult end -- Ignore invalid definition, treating it as a comment. end end end localfunctionconvert_lookup(ucode,value,scaled_top,want_link,si,options) locallookup=require(convert_module)._unit returnlookup(ucode,{ value=value, scaled_top=scaled_top, link=want_link, si=si, sort=options.sortable, }) end localfunctionget_unit(ucode,value,scaled_top,options) localwant_link=options.want_link ifscaled_topthen want_link=options.want_per_link end localdata=mw.loadData(data_module) localresult=options.want_longscaleand get_builtin_unit(ucode,data.builtin_units_long_scale)or get_builtin_unit(ucode,data.builtin_units) localsi,use_convert ifresultthen ifresult.aliasthen ucode=result.symbol use_convert=true end ifresult.scalethen -- Setting si means convert will use the unit as given, and the sort key -- will be calculated from the value without any extra scaling that may -- occur if convert found the unit code. For example, if val defines the -- unit 'year' with a scale and if si were not set, convert would also apply -- its own scale because convert knows that a year is 31,557,600 seconds. si={result.symbol,result.link} value=value*result.scale end ifresult.sithen ucode=result.ucodeorucode si={result.symbol,result.link} use_convert=true end else result={} use_convert=true end localconvert_unit=convert_lookup(ucode,value,scaled_top,want_link,si,options) result.sortkey=convert_unit.sortspan ifuse_convertthen result.text=convert_unit.text result.scaled_top=convert_unit.scaled_value else ifwant_linkthen result.text='[['..result.link..'|'..result.symbol..']]' else result.text=result.symbol end result.scaled_top=value end returnresult end localfunctionmakeunit(value,options) -- Return table of information for the requested unit and options, or -- return nil if no unit. options=optionsor{} localunit localucode=options.u localpercode=options.per ifucodethen unit=get_unit(ucode,value,nil,options) elseifpercodethen unit={nospace=true,scaled_top=value} else returnnil end localtext=unit.textor'' localsortkey=unit.sortkey ifpercodethen localfunctionbracketed(code,text) returncode:find('[*./]')and'('..text..')'ortext end localperunit=get_unit(percode,1,unit.scaled_top,options) text=(ucodeandbracketed(ucode,text)or'').. '/'..bracketed(percode,perunit.text) sortkey=perunit.sortkey end ifnot(unit.nospaceoroptions.nospace)then text=' '..text end return{text=text,isangle=unit.isangle,sortkey=sortkey} end localfunctionlist_units(mode) -- Return wikitext to list the built-in units. -- A unit code should not contain wikimarkup so don't bother escaping. localdata=mw.loadData(data_module) localdefinitions=data.builtin_units..data.builtin_units_long_scale locallast_was_blank=true localn=0 localresult={} localfunctionadd(line) ifline==''then last_was_blank=true else iflast_was_blankandn>0then n=n+1 result[n]='' end last_was_blank=false n=n+1 result[n]=line end end localsi_prefixes={ -- These are the prefixes recognized by convert; u is accepted for micro. y='y', z='z', a='a', f='f', p='p', n='n', u='μ', ['μ']='μ', m='m', c='c', d='d', da='da', h='h', k='k', M='M', G='G', T='T', P='P', E='E', Z='Z', Y='Y', } localfunctionis_valid(ucode,unit) ifunitandnotunit.more_ignoredthen assert(type(unit.symbol)=='string'andunit.symbol~='') ifunit.aliasthen ifunit.linkorunit.scale_textorunit.sithen returnfalse end end ifunit.sithen ifunit.scale_textthen returnfalse end ucode=unit.ucodeorucode localbase=unit.symbol ifucode==basethen unit.display=base returntrue end localplen=#ucode-#base ifplen>0then localprefix=si_prefixes[ucode:sub(1,plen)] ifprefixanducode:sub(plen+1)==basethen unit.display=prefix..base returntrue end end else unit.display=unit.symbol returntrue end end returnfalse end locallookup=require(convert_module)._unit localfunctionshow_convert(ucode,unit) -- If a built-in unit defines a scale or sets the SI flag, any unit defined in -- convert is not used (the scale or SI prefix's scale is used for a sort key). -- If there is no scale or SI flag, and the unit is not defined in convert, -- the sort key may not be correct; this allows such units to be identified. ifnot(unit.siorunit.scale_text)then ifmode=='convert'then unit.show=notlookup(unit.aliasandunit.symbolorucode).unknown unit.show_text='CONVERT' elseifmode=='unknown'then unit.show=lookup(unit.aliasandunit.symbolorucode).unknown unit.show_text='UNKNOWN' elseifnotunit.aliasthen -- Show convert's scale in square brackets ('[1]' for an unknown unit). -- Don't show scale for an alias because it's misleading for temperature -- and an alias is probably not useful for anything else. localscale=lookup(ucode,{value=1,sort='on'}).scaled_value iftype(scale)=='number'then scale=string.format('%.5g',scale):gsub('e%+?(%-?)0*(%d+)','e%1%2') else scale='?' end unit.show=true unit.show_text='['..scale..']' end end end forlineindefinitions:gmatch('([^\n]*)\n')do localpos,_=line:find(' ',1,true) ifposthen localucode=line:sub(1,pos-1) localunit=get_builtin_unit(ucode,'\n'..line..'\n') ifis_valid(ucode,unit)then show_convert(ucode,unit) localflags,text ifunit.aliasthen text=unit.symbol else text='[['..unit.link..'|'..unit.display..']]' end ifunit.isanglethen unit.nospace=nil-- don't show redundant flag end for_,finipairs({ {'alias','ALIAS'}, {'isangle','ANGLE'}, {'nospace','NOSPACE'}, {'si','SI'}, {'scale_text',unit.scale_text}, {'show',unit.show_text}, })do ifunit[f[1]]then localt=f[2] ift:match('^%u+$')then t='<small>'..t..'</small>' end ifflagsthen flags=flags..' '..t else flags=t end end end ifflagsthen text=text..' • '..flags end add(ucode..' = '..text..'<br />') else add(line..' ◆だいやまーく <b>invalid definition</b><br />') end else add(line) end end returntable.concat(result,'\n') end localdelimit_groups=require('Module:Gapnum').groups localfunctiondelimit(sign,numstr,fmt) -- Return sign and numstr (unsigned digits or numdot only) after formatting. -- Four-digit integers are not formatted with gaps. fmt=(fmtor''):lower() iffmt=='none'or(fmt==''and#numstr==4andnumstr:match('^%d+$'))then returnsign..numstr end -- Group number by integer and decimal parts. -- If there is no decimal part, delimit_groups returns only one table. localipart,dpart=delimit_groups(numstr) localresult iffmt=='commas'then result=sign..table.concat(ipart,numsep) ifdpartthen result=result..numdot..table.concat(dpart) end else -- Delimit with a small gap by default. localgroups={} groups[1]=table.remove(ipart,1) for_,vinipairs(ipart)do table.insert(groups,'<span style="margin-left:.25em;">'..v..'</span>') end ifdpartthen table.insert(groups,numdot..(table.remove(dpart,1)or'')) for_,vinipairs(dpart)do table.insert(groups,'<span style="margin-left:.25em;">'..v..'</span>') end end result=sign..table.concat(groups) end returnresult end localfunctionsup_sub(sup,sub,align) -- Return the same result as Module:Su except val defaults to align=right. ifalign=='l'oralign=='left'then align='left' elseifalign=='c'oralign=='center'then align='center' else align='right' end return'<span style="display:inline-block;margin-bottom:-0.3em;vertical-align:-0.4em;line-height:1.2em;font-size:85%;text-align:'.. align..';">'..sup..'<br />'..sub..'</span>' end localfunctionrange_text(items,unit_table,options) localfmt=options.fmt localnend=items.nendor'' ifitems.isrepeatorunit_table.isanglethen nend=nend..unit_table.text end localtext='' fori=1,#itemsdo ifi%2==0then text=text..items[i] else text=text..delimit(items[i].sign,items[i].clean,fmt)..nend end end returntext end localfunctionuncertainty_text(uncertainty,unit_table,options) localangle,text,need_parens ifunit_table.isanglethen angle=unit_table.text end localupper=uncertainty.upperor{} locallower=uncertainty.loweror{} localuncU=upper.clean ifuncUthen localfmt=options.fmt localuncL=lower.clean ifuncLthen uncU=delimit('+',uncU,fmt)..(upper.errendor'') uncL=delimit('−',uncL,fmt)..(lower.errendor'') ifanglethen uncU=uncU..angle uncL=uncL..angle end text=(angleor'').. '<span style="margin-left:0.3em;">'.. sup_sub(uncU,uncL,options.align).. '</span>' else ifupper.parensthen text='('..uncU..')'-- old template did not delimit else text=(angleor'').. '<span style="margin-left:0.225em;margin-right:0.225em;">±</span>'.. delimit('',uncU,fmt) need_parens=true end ifuncertainty.errendthen text=text..uncertainty.errend end ifanglethen text=text..angle end end else ifanglethen text=angle end end returntext,need_parens end localfunction_main(values,unit_spec,options) ifoptions.sandboxthen data_module=data_module..'/sandbox' convert_module=convert_module..'/sandbox' end localaction=options.action ifactionthen ifaction=='list'then -- Kludge: am using the align parameter (a=xxx) for type of list. returnlist_units(options.align) end returnvalerror('invalid action "'..action..'".',options.nocat) end localnumber=values.numberor(values.numbersandvalues.numbers[1])or{} locale_10=options.eor{} localnovalue=(number.value==nilande_10.clean==nil) localfmt=options.fmt localwant_sort=true localsortable=options.sortable ifsortable=='off'or(sortable==nilandnovalue)then want_sort=false elseifsortable=='debug'then -- Same as sortable = 'on' but the sort key is displayed. else sortable='on' end localsort_value=1 ifwant_sortthen sort_value=number.valueor1 ife_10.valueandsort_value~=0then -- The 'if' avoids {{val|0|e=1234}} giving an invalid sort_value due to overflow. sort_value=sort_value*10^e_10.value end end localunit_table=makeunit(sort_value,{ u=unit_spec.u, want_link=unit_spec.want_link, per=unit_spec.per, want_per_link=unit_spec.want_per_link, nospace=novalue, want_longscale=unit_spec.want_longscale, sortable=sortable, }) localsortkey ifunit_tablethen ifwant_sortthen sortkey=unit_table.sortkey end else unit_table={text=''} ifwant_sortthen sortkey=convert_lookup('dummy',sort_value,nil,nil,nil,{sortable=sortable}).sortspan end end localfinal_unit=unit_table.isangleand''orunit_table.text locale_text,n_text,need_parens localuncertainty=values.uncertainty ifuncertaintythen ifnumber.cleanthen n_text=delimit(number.sign,number.clean,fmt)..(number.nendor'') localtext text,need_parens=uncertainty_text(uncertainty,unit_table,options) iftextthen n_text=n_text..text end else n_text='' end else ifvalues.numbers.isrepeatthen final_unit='' end n_text=range_text(values.numbers,unit_table,options) need_parens=true end ife_10.cleanthen ifneed_parensthen n_text='('..n_text..')' end e_text='10<sup>'..delimit(e_10.sign,e_10.clean,fmt)..'</sup>' ifnumber.cleanthen e_text='<span style="margin-left:0.25em;margin-right:0.15em;"&g×ばつ</span>'..e_text end else e_text='' end localresult= (sortkeyor'').. (options.prefixor'').. n_text.. e_text.. final_unit.. (options.suffixor'') ifresult~=''then result='<span class="nowrap">'..result..'</span>' end returnresult..(options.warningor'') end localfunctioncheck_parameters(args,has_ranges,nocat) -- Return warning text for the first problem parameter found, or nothing if ok. localwhitelist={ a=true, action=true, debug=true, e=true, ['end']=true, errend=true, ['+errend']=true, ['-errend']=true, fmt=true, ['long scale']=true, long_scale=true, longscale=true, nocategory=true, p=true, s=true, sortable=true, u=true, ul=true, up=true, upl=true, } fork,vinpairs(args)do iftype(k)=='string'andnotwhitelist[k]then localwarning=string.format(mtext['mt-val-not-supported'],k,v) returnvalerror(warning,nocat,true) end end ifnothas_rangesandargs[4]then returnvalerror(mtext['mt-ignore-parameter4'],nocat,true) end end localfunctionmain(frame) localgetArgs=require('Module:Arguments').getArgs localargs=getArgs(frame,{wrappers={'Template:Val'}}) localnocat=args.nocategory localnumbers={}-- table of number tables, perhaps with range text localmsg=get_args(numbers,args) ifmsgthen returnvalerror(msg,nocat) end ifargs.uandargs.ulthen returnvalerror(mtext['mt-both-u-ul'],nocat) end ifargs.upandargs.uplthen returnvalerror(mtext['mt-both-up-upl'],nocat) end localvalues ifnumbers.has_rangesthen -- Multiple values with range separators but no uncertainty. numbers.nend=args['end'] values={ numbers=numbers, } else -- A single value with optional uncertainty. localfunctionsetfield(i,dst,src) localv=args[src] ifvthen ifnumbers[i]then numbers[i][dst]=v else numbers[i]={[dst]=v} end end end setfield(1,'nend','end') setfield(2,'errend','+errend') setfield(3,'errend','-errend') values={ number=numbers[1], uncertainty={ upper=numbers[2], lower=numbers[3], errend=args.errend, } } end localunit_spec={ u=args.ulorargs.u, want_link=args.ul~=nil, per=args.uplorargs.up, want_per_link=args.upl~=nil, want_longscale=(args.longscaleorargs.long_scaleorargs['long scale'])=='on', } localoptions={ action=args.action, align=args.a, e=numbers.e, fmt=args.fmt, nocat=nocat, prefix=args.p, sandbox=string.find(frame:getTitle(),'sandbox',1,true)~=nil, sortable=args.sortableor(args.debug=='yes'and'debug'ornil), suffix=args.s, warning=check_parameters(args,numbers.has_ranges,nocat), } return_main(values,unit_spec,options) end return{main=main,_main=_main}