This manual documentsLua as it is used in MediaWiki with theScribunto extension.Some parts are derived from theLua 5.1 reference manual, which is available under theMIT license.
![]() | This page documents the latest version of the Scribunto extension. Some features may not be deployed yet. |
On a MediaWiki wiki with Scribunto enabled,create a page with a title starting withModule:
, for example "Module:Bananas".Into this new page, copy the following text:
localp={}--p stands for packagefunctionp.hello(frame)return"Hello, world!"endreturnp
Save that, then on another (non-module) page, as on asandbox page, write:
{{#invoke:Bananas|hello}}
Except that you should replace "Bananas" with whatever you called your module. This will call the "hello" function exported from that module. The{{#invoke:Bananas|hello}}
will be replaced with the text that the function returned, in this case, "Hello, world!"
It's generally a good idea to invoke Lua code from the context of a template.This means that from the perspective of a calling page, the syntax is independent of whether the template logic is implemented in Lua or in wikitext.It also avoids the introduction of additional complex syntax into the content namespace of a wiki.
The module itself must return a Lua table containing the functions that may be called by{{#invoke:}}
.Generally, as shown above, a local variable is declared holding a table, functions are added to this table, and the table is returned at the end of the module code.
Any functions that are not added to this table, whether local or global, will not be accessible by{{#invoke:}}
, but globals might be accessible from other modules loaded usingrequire()
.It is generally good style for the module to declare all functions and variables local.
Functions called by{{#invoke:}}
will be passed a single parameter, that being aframe object. To access the parameters passed to the{{#invoke:}}
, code will typically use theargs
table of that frame object. It's also possible to access the parameters passed to the template containing the{{#invoke:}}
by usingframe:getParent()
and accessing that frame'sargs
.
This frame object is also used to access context-specific features of the wikitext parser, such ascalling parser functions,expanding templates, andexpanding arbitrary wikitext strings.
The module function should usually return a single string; whatever values are returned will be passed throughtostring() and then concatenated with no separator. This string is incorporated into the wikitext as the result of the{{#invoke:}}
.
At this point in the page parse, templates have already been expanded, parser functions and extension tags have already been processed, andpre-save transforms (i.e., signature tilde expansion, pipe trick, etc.) have already happened. Therefore the module cannot use these features in its output text. For example, if a module returns"Hello, [[world]]! {{welcome}}"
, the page will read "Hello,world! {{welcome}}".
On the other hand,subst is handled at an earlier stage of processing, so with{{subst:#invoke:}}
only other attempted substitutions will be processed. Since the failed substitution will remain in the wikitext, they will then be processed on thenext edit. This should generally be avoided.
Scribunto allows modules to be documented by automatically associating the module with a wikitext documentation page; by default, the "/doc" subpage of the module is used for this purpose and is transcluded above the module source code on the module page. For example, the documentation for "Module:Bananas" would be at "Module:Bananas/doc".
This can be configured using the followingsystem messages:
scribunto-doc-page-name
— Sets the name of the page used for documentation. The name of the module (without the Module: prefix) is passed as$1
. If in the module namespace, the pages specified here will be interpreted as wikitext rather than Lua source and may not be used with{{#invoke:}}
. The default is "Module:$1/doc", i.e. the /doc subpage of the module. Note that parser functions and other brace expansion may not be used in this message.scribunto-doc-page-does-not-exist
— Message displayed when the doc page does not exist. The name of the page is passed as$1
. The default is empty.scribunto-doc-page-show
— Message displayed when the doc page does exist. The name of the page is passed as$1
. The default is to transclude the documentation page.scribunto-doc-page-header
— Header displayed when viewing the documentation page itself. The name of the module (with Module: prefix) being documented is passed as$1
. The default simply displays a short explanation in italics.Note that modules cannot be directly categorized.Category insertions can be placed on the documentation page inside<includeonly>...</includeonly>
tags, where they will be applied to the module when the documentation page is transcluded onto the module page.
To rename or move a module, use theMove Page link in the Tools sidebar. You will want to move both the module itself, as well as the subpage containing its documentation.
MediaWiki version: | 1.42 Gerrit change 574086 |
Since release 1.42, Scribunto recognizes one particular syntax for redirects (so they’re highlighted on special pages, appear on Special:WhatLinksHere, and so on), and also produces redirects when renaming/moving a module, similarly to how renaming of wikitext pages works (before that, module renames left no redirects behind, now extra rights are needed to suppress the redirect).
To manually create a module redirect, use the following syntax (which is valid Lua code, and worked like a redirect even before 1.42, but without MediaWiki recognizing it as such):
returnrequire[[Module:Foo]]
ReplaceFoo
with the name of the module you'd like to redirect to.
Please note that other similarly valid Lua syntax variations (e.g. using quotation marks instead of square brackets, using parentheses around therequire
parameter, or even whitespace variations) are still not recognized by MediaWiki as redirects.
Aname (also called anidentifier) in Lua can be any string of letters, digits, and underscores, not beginning with a digit. Names are case-sensitive; "foo", "Foo", and "FOO" are all different names.
The following keywords are reserved and may not be used as names:
and
break
do
else
elseif
end
false
for
function
if
in
local
nil
not
or
repeat
return
then
true
until
while
Names starting with an underscore followed by uppercase letters are reserved for internal Lua global variables.
Other tokens are:
#
%
(
)
*
+
,
-
--
.
..
...
/
:
;
<
<=
=
==
>
>=
[
]
^
{
}
~=
A comment starts with a--
anywhere outside a string. If the--
is immediately followed byan opening long bracket, the comment continues to the corresponding closing long bracket; otherwise the comment runs to the end of the current line.
-- A comment in Lua starts with a double-hyphen and runs to the end of the line.--[[ Multi-line strings & comments are adorned with double square brackets. ]]--[=[ Comments like this can have other --[[comments]] nested. ]=]--[==[ Comments like this can have other --[===[ long --[=[comments]=] --nested ]===] multiple times, even if all of them are --[[ not delimited with matching long brackets! ]===] ]==]
Lua is a dynamically-typed language, which means that variables and function arguments have no type, only the values assigned to them. All values carry a type.
Lua has eight basic data types, however only six are relevant to the Scribunto extension. Thetype()
function will return the type of a value.
Thetostring()
function will convert a value to a string. Thetonumber()
function will convert a value to a number if possible, and otherwise will return nil. There are no explicit functions to convert a value to other data types.
Numbers are automatically converted to strings when used where a string is expected, e.g. when used with the concatenation operator. Strings recognized bytonumber()
are automatically converted to numbers when used with arithmetic operators. When a boolean value is expected, all values other than nil and false are considered to be true.
"nil"
is the data type ofnil
, which exists to represent the absence of a value.
Nil may not be used as a key in a table, and there is no difference between an unassigned table key and a key assigned a nil value.
When converted to a string, the result is"nil"
. When converted to boolean, nil is considered false.
Note: Lua does make a distinction betweennil
and nothing at all in some limited situations.For example,tostring(nil)
returns"nil"
, buttostring()
throws an error, as the first parameter is required.This distinction is particularly relevant to theselect() function.
Boolean values aretrue
andfalse
.
When converted to a string, the result is"true"
or"false"
.
Unlike many other languages, boolean values may not be directly converted to numbers. And unlike many other languages, onlyfalse
and nil are considered false for boolean conversion; the number 0 and the empty string are both considered true.
Lua strings are considered a series of 8-bit bytes; it is up to the application to interpret them in any particular encoding.
String literals may be delimited by either single or double quotes ('
or"
); like JavaScript and unlike PHP, there is no difference between the two. The following escape sequences are recognized:
\a
(bell, byte 7)\b
(backspace, byte 8)\t
(horizontal tab, byte 9)\n
(newline, byte 10)\v
(vertical tab, byte 11)\f
(form feed, byte 12)\r
(carriage return, byte 13)\"
(double quote, byte 34)\'
(single quote, byte 39)\\
(backslash, byte 92)A literal newline may also be included in a string by preceding it with a backslash. Bytes may also be specified using an escape sequence '\ddd', whereddd is the decimal value of the byte in the range 0–255. To include Unicode characters using escape sequences, the individual bytes for theUTF-8 encoding must be specified; in general, it will be more straightforward to enter the Unicode characters directly.
Literal strings can also be defined usinglong brackets.An opening long bracket consists of an opening square bracket followed by zero or more equal signs followed by another opening square bracket, e.g.[[
,[=[
, or[=====[
.The opening long bracket must be matched by the corresponding closing long bracket, e.g.]]
,]=]
, or]=====]
.As a special case, if an opening long bracket is immediately followed by a newline then the newline is not included in the string, but a newline just before the closing long bracket is kept.Strings delimited by long brackets do not interpret escape sequences.
-- This long stringfoo=[[bar\tbaz]]-- is equivalent to this quote-delimited stringfoo='bar\\tbaz\n'
Note that all strings are considered true when converted to boolean. This is unlike most other languages, where the empty string is usually considered false.
Lua has only one numeric type, which is typically represented internally as a64-bit double-precision floating-point value. In this format, integers between-9007199254740991
(-253 + 1) and9007199254740991
(253 - 1) may be represented exactly; larger numbers and numbers with a fractional part may suffer from round-off error.
Number constants are specified using a period (.
) as a decimal separator and without grouping separators, e.g.123456.78
.Numbers may also be represented usingE notation without spaces, e.g.1.23e-10
,123.45e20
, or1.23E+5
.Integers may also be specified in hexadecimal notation using a0x
prefix, e.g.0x3A
.
A handful of number values are handled in a special way:
math
library, asmath.huge
and-math.huge
, or through numerical operations such as1/0
and-1/0
.0
and-0
(see theIEEE 754 for more information on signed zeros).0
and-0
are strictly equivalent for almost all purposes, but behave differently in a small number of numerical operations (e.g.1/0
returns infinity, while1/-0
returns negative infinity). The distinction also affects conversions from number to string (and vice-versa).0/0
evaluates to negative NaN. Note that both NaNs have the unique quality that any comparison which involves them evaluates tofalse
(which means they do not even evaluate as being equal to themselves). The only practical distinction between the two is on type conversion to and from string (see below).Note that all numbers (including0
,-0
, the infinities and NaNs) are considered true when converted to boolean.This is unlike most other languages, where0
is usually considered false.When converted to a string, finite numbers are represented in decimal, and E notation if 1014 or greater (e.g."1e+14"
); the infinities are"inf"
and"-inf"
; and the NaNs are"nan"
and"-nan"
.
Known bug: the Lua interpreter will treat all instances of0
and-0
as whichever of the two is encountered first when the script is compiled, which means that the return values oftostring(0)
,1/-0
(and so on) are affected by where they occur in the code.This can cause unexpected results, particularly if all instances of0
are converted to"-0"
on return.If necessary, this can be circumvented by generating zero values usingtonumber("0")
andtonumber("-0")
, which doesn't seem to cause or be affected by the issue. See[1].
Lua tables are associative arrays, much like PHP arrays and JavaScript objects.
Tables are created using curly braces. The empty table is{}
. To populate fields on creation, a comma- and/or semicolon-separated list of field specifiers may be included in the braces. These take any of several forms:
[expression1] =expression2
uses the (first) value ofexpression1 as the key and the (first) value ofexpression2 as the value.name =expression
is equivalent to["name"] =expression
expression
is roughly equivalent to[i] =expression
, wherei is an integer starting at 1 and incrementing with each field specification of this form. If this is the last field specifier and the expression has multiple values, all values are used; otherwise only the first is kept.The fields in a table are accessed using bracket notation, e.g.table[key]
. String keys that are also validnames may also be accessed using dot notation, e.g.table.key
is equivalent totable['key']
. Calling a function that is a value in the table may use colon notation; for example,table:func( ... )
, which is equivalent totable['func']( table, ... )
ortable.func( table, ... )
.
Anarray (also called asequence orlist) is a table with non-nil values for all positive integers from 1 to N and no value (nil) for all positive integers greater than N. Many Lua functions operate only on arrays, and ignore non-positive-integer keys.
Unlike many other languages such as PHP or JavaScript, any value except nil and NaN may be used as a key and no type conversion is performed. These are all valid and distinct:
-- Create tablet={}t["foo"]="foo"t.bar="bar"t[1]="one"t[2]="two"t[3]="three"t[12]="the number twelve"t["12"]="the string twelve"t[true]="true"t[tonumber]="yes, even functions may be table keys"t[t]="yes, a table may be a table key too. Even in itself."-- This creates a table roughly equivalent to the abovet2={["foo"]="foo",bar="bar","one","two",[12]="the number twelve",["12"]="the string twelve","three",[true]="true",[tonumber]="yes, even functions may be table keys",}t2[t2]="yes, a table may be a table key too. Even in itself."
Similarly, any value except nil may be stored as a value in a table. Storing nil is equivalent to deleting the key from the table, and accessing any key that has not been set will result in a nil value.
Note that tables are never implicitly copied in Lua; if a table is passed as an argument to the function and the function manipulates the keys or values in the table, those changes will be visible in the caller.
When converted to a string, the usual result is "table" but may be overridden using the__tostring
metamethod. Even the empty table is considered true as a boolean.
Functions in Lua are first-class values: they may be created anonymously, passed as arguments, assigned to variables, and so on.
Functions are created using thefunction
keyword, and called using parentheses.Syntactic sugar is available for named functions, local functions, and functions that act like member functions to a table. SeeFunction declarations andFunction calls below for details.
Lua functions areclosures, meaning that they maintain a reference to the scope in which they are declared and can access and manipulate variables in that scope.
Like tables, if a function is assigned to a different variable or passed as an argument to another function, it is still the same underlying "function object" that will be called.
When converted to a string, the result is "function".
Theuserdata type is used to hold opaque values for extensions to Lua written in other languages; for example, a userdata might be used to hold a C pointer or struct. To allow for use of Scribunto in hosting environments where custom-compiled code is not allowed, no such extensions are used.
Thethread type represents the handles for coroutines, which are not available in Scribunto's sandbox.
There is a strict limit of max 60 unique upvalues accessed inside a function. An upvalue is a value declared outside of a function and used inside it. As upvalues do count:
A violation of the limit can be triggered by a use of such a variable or function, not by its mere presence or availability. Repeated access to same upvalue does not exhaust the limit further.
Every table may have an associated table known as ametatable. The fields in the metatable are used by some operators and functions to specify different or fallback behavior for the table. The metatable for a table may be accessed using thegetmetatable() function, and set with thesetmetatable() function.
When being accessed for their meta functions, metatable fields are accessed as if withrawget().
Metatable fields that affect the table itself are:
t[key]
would return nil. If the value of this field is a table, the access will be repeated in that table, i.e.__index[key]
(which may invoke that table's metatable's __index). If the value of this field is a function, the function will be called as__index( t, key )
. Therawget() function bypasses this metamethod.t[key] = value
whererawget( t, key )
would return nil. If the value of this field is a table, the assignment will be made to that table instead, i.e.__newindex[key] = value
(which may invoke that table's metatable's __newindex). If the value of this field is a function, the function will be called as__newindex( t, key, value )
. Therawset() function bypasses this metamethod.t( ··· )
. The value must be a function, which is called as something like__call( t, ··· )
.Other metatable fields include:
Note: In Lua, all strings also share a single metatable, in which__index
refers to thestring
table. This metatable is not accessible in Scribunto, nor is the referencedstring
table; the string table available to modules is a copy.
Variables are places that store values. There are three kinds of variables in Lua: global variables, local variables, and table fields.
Aname represents a global or local variable (or a function argument, which is just a kind of local variable). Variables are assumed to be global unless explicitly declared as local using thelocal
keyword. Any variable that has not been assigned a value is considered to have a nil value.
Global variables are stored in a standard Lua table called anenvironment; this table is often available as the global variable_G
. It is possible to set a metatable for this global variable table; the __index and __newindex metamethods will be called for accesses of and assignments to global variables just as they would for accesses of and assignments to fields in any other table.
The environment for a function may be accessed using thegetfenv() function and changed using thesetfenv() function; in Scribunto, these functions are severely restricted if they are available at all.
Local variables are lexically scoped; seeLocal variable declarations for details.
Anexpression is something that has values: literals (numbers, strings, true, false, nil), anonymous function declarations, table constructors, variable references, function calls, thevararg expression, expressions wrapped in parentheses, unary operators applied to expressions, and expressions combined with binary operators.
Most expressions have one value; function calls and the vararg expression can have any number. Note that wrapping a function call or vararg expression in parentheses will lose all except the first value.
Expression lists are comma-separated lists of expressions. All except the last expression are forced to one value (dropping additional values, or using nil if the expression has no values); all values from the last expression are included in the values of the expression list.
Lua supports the usual arithmetic operators: addition, subtraction, multiplication, division, modulo, exponentiation, and negation.
When all operands are numbers or strings for whichtonumber() returns non-nil, the operations have their usual meaning.
If either operand is a table with an appropriatemetamethod, the metamethod will be called.
Operator | Function | Example | Metamethod | Notes |
---|---|---|---|---|
+ | Addition | a + b | __add | |
- | Subtraction | a - b | __sub | |
* | Multiplication | a * b | __mul | |
/ | Division | a / b | __div | division by zero is not an error; NaN or infinity will be returned |
% | Modulo | a % b | __mod | defined asa % b == a - math.floor( a / b ) * b |
^ | Exponentiation | a ^ b | __pow | non-integer exponents are allowed |
- | Negation | -a | __unm |
The relational operators in Lua are==
,~=
,<
,>
,<=
, and>=
. The result of a relational operator is always a boolean.
Equality (==
) first compares the types of its operands; if they are different, the result is false. Then it compares the values: nil, boolean, number, and string are compared in the expected manner. Functions are equal if they refer to the exact same function object;function() end == function() end
will return false, as it is comparing two different anonymous functions. Tables are by default compared in the same manner, but this may be changed using the __eqmetamethod.
Inequality (~=
) is the exact negation of equality.
For the ordering operators, if both are numbers or both are strings, they are compared directly. Next, metamethods are checked:
a < b
uses__lt
a <= b
uses__le
if available, or if__lt
is available then it is considered equivalent tonot ( b < a )
a > b
is considered equivalent tob < a
a >= b
is considered equivalent tob <= a
If the necessary metamethods are not available, an error is raised.
The logical operators areand
,or
, andnot
. All use the standard interpretation where nil and false are considered false and anything else is considered true.
Forand
, if the left operand is considered false then it is returned and the second operand is not evaluated; otherwise the second operand is returned.
Foror
, if the left operand is considered true then it is returned and the second operand is not evaluated; otherwise the second operand is returned.
Fornot
, the result is always true or false.
Note thatand
andor
short circuit. For example,foo() or bar()
will only callbar()
iffoo()
returns false or nil as its first value.
The concatenation operator is two dots, used asa .. b
. If both operands are numbers or strings, they are converted to strings and concatenated. Otherwise if a __concatmetamethod is available, it is used. Otherwise, an error is raised.
Note that Lua strings are immutable and Lua does not provide any sort of "string builder", so a loop that repeatedly doesa = a .. b
will have to create a new string for each iteration and eventually garbage-collect the old strings. If many strings need concatenating, it may be faster to usestring.format() or to insert all the strings into asequence and usetable.concat() at the end.
The length operator is#
, used as#a
. Ifa
is a string, it returns the length in bytes. Ifa
is asequence table, it returns the length of the sequence.
Ifa
is a table that isnot a sequence, the#a
may return 0 or any value N such thata[N]
is not nil anda[N+1]
is nil, even if there are non-nil values at higher indexes. For example,
-- This is not a sequence, because a[3] is nil and a[4] is not.a={1,2,nil,4}-- This may output either 2 or 4.-- And this may change even if the table is not modified.mw.log(#a)
Lua's operator precedence ororder of operations, from highest to lowest:
^
not
#
-
(negation)*
/
%
+
-
(subtraction)..
<
>
<=
>=
~=
==
and
or
Within a precedence level, most binary operators are left-associative, i.e.a / b / c
is interpreted as(a / b) / c
. Exponentiation and concatenation are right-associative, i.e.a ^ b ^ c
is interpreted asa ^ (b ^ c)
.
Lua function calls look like those in most other languages: a name followed by a list of arguments in parentheses:
func(expression-list )
As is usual with expression lists in Lua, the last expression in the list may supply multiple argument values.
If the function is called with fewer values in the expression list than there are arguments in the function definition, the extra arguments will have a nil value. If the expression list contains more values than there are arguments, the excess values are discarded. It is also possible for a function to take a variable number of arguments; seeFunction declarations for details.
Lua also allows direct calling of a function return value, i.e.func()()
. If an expression more complex than a variable access is needed to determine the function to be called, a parenthesized expression may be used in place of the variable access.
Lua has syntactic sugar for two common cases. The first is when a table is being used as an object, and the function is to be called as a method on the object. The syntax
table:name(expression-list )
is exactly equivalent to
table.name( table,expression-list )
The second common case is Lua's method of implementingnamed arguments by passing a table containing the name-to-value mappings as the only positional argument to the function. In this case, the parentheses around the argument list may be omitted. This also works if the function is to be passed a single literal string. For example, the calls
func{ arg1 =exp, arg2 =exp }func"string"
are equivalent to
func( { arg1 =exp, arg2 =exp } )func( "string" )
These may be combined; the following calls are equivalent:
table:name{ arg1 =exp, arg2 =exp }table.name( table, { arg1 =exp, arg2 =exp } )
The syntax for function declaration looks like this:
functionnameoptional(var-listoptional)blockend
All variables invar-list are local to the function, with values assigned from the expression list in thefunction call. Additional local variables may be declared inside the block.
When the function is called, the statements inblock are executed after local variables corresponding tovar-list are created and assigned values. If areturn statement is reached, the block is exited and the values of the function call expression are those given by the return statement. If execution reaches the end of the function's block without encountering a return statement, the result of the function call expression has zero values.
Lua functions arelexical closures. A common idiom is to declare "private static" variables as locals in the scope where the function is declared. For example,
-- This returns a function that adds a number to its argumentfunctionmakeAdder(n)returnfunction(x)-- The variable n from the outer scope is available here to be added to xreturnx+nendendlocaladd5=makeAdder(5)mw.log(add5(6))-- prints 11
A function may be declared to accept a variable number of arguments, by specifying...
as the final item in thevar-list:
Within the block, the varargs expression...
may be used, with the result being all the extra values in the function call. For example,
localjoin=function(separator,...)-- get the extra arguments as a new tablelocalargs={...}-- get the count of extra arguments, correctlylocaln=select('#',...)returntable.concat(args,separator,1,n)endjoin(', ','foo','bar','baz')-- returns the string "foo, bar, baz"
Theselect() function is designed to work with the varargs expression; in particular,select( '#', ... )
should be used instead of#{ ... }
to count the number of values in the varargs expression, because{ ... }
may not be asequence.
Lua provides syntactic sugar to combine function declaration and assignment to a variable; seeFunction declaration statements for details.
Note that this will not work:
localfactorial=function(n)ifn<=2thenreturnnelsereturnn*factorial(n-1)endend
Since the function declaration is processed before the local variable assignment statement is complete, "factorial" inside the function body refers to the (probably undefined) variable of that name in an outer scope. This problem may be avoided by declaring the local variable first and then assigning it in a subsequent statement, or by using thefunction declaration statement syntax.
Astatement is the basic unit of execution: one assignment, control structure, function call, variable declaration, etc.
Achunk is a sequence of statements, optionally separated by semicolons. A chunk is basically considered the body of an anonymous function, so it can declare local variables, receive arguments, and return values.
Ablock is also a sequence of statements, just like a chunk. A block can be delimited to create a single statement:doblock end
. These may be used to limit the scope of local variables, or to add areturn
orbreak
in the middle of another block.
variable-list =expression-list
Thevariable-list is a comma-separated list of variables; theexpression-list is a comma-separated list of one or more expressions. All expressions are evaluated before any assignments are performed, soa, b = b, a
will swap the values ofa andb.
localvariable-list
localvariable-list =expression-list
Local variables may be declared anywhere within ablock orchunk. The first form, without an expression list, declares the variables but does not assign a value so all variables have nil as a value. The second form assigns values to the local variables, as described inAssignments above.
Note that visibility of the local variable begins with the statement after the local variable declaration. So a declaration likelocal x = x
declares a local variable x and assigns it the value of x from the outer scope. The local variable remains in scope until the end of the innermost block containing the local variable declaration.
whileexp doblock end
The while statement repeats a block as long as an expression evaluates to a true value.
repeatblock untilexp
The repeat statement repeats a block until an expression evaluates to a true value. Local variables declared inside the block may be accessed in the expression.
forname =exp1,exp2,exp3 doblock end
forname =exp1,exp2 doblock end
This first form of the for loop will declare a local variable, and repeat the block for values fromexp1 toexp2 addingexp3 on each iteration. Note thatexp3 may be omitted entirely, in which case 1 is used, but non-numeric values such asnil
andfalse
are an error. All expressions are evaluated once before the loop is started.
This form of the for loop is roughly equivalent to
dolocalvar,limit,step=tonumber(exp1),tonumber(exp2),tonumber(exp3)ifnot(varandlimitandstep)thenerror()endwhile(step>0andvar<=limit)or(step<=0andvar>=limit)dolocalname=varblockvar=var+stependend
except that the variables var, limit, and step are not accessible anywhere else. Note that the variablename is local to the block; to use the value after the loop, it must be copied to a variable declared outside the loop.
forvar-list inexpression-list doblock end
The second form of the for loop works withiterator functions. As in the first form, theexpression-list is evaluated only once before beginning the loop.
This form of the for loop is roughly equivalent to
dolocalfunc,static,var=expression-listwhiletruedolocalvar-list=func(static,var)var=var1-- ''var1'' is the first variable in ''var-list''ifvar==nilthenbreakendblockendend
except that again the variables func, static, and var are not accessible anywhere else. Note that the variables invar-list are local to the block; to use them after the loop, they must be copied to variables declared outside the loop.
Often theexpression-list is a single function call that returns the three values. If the iterator function can be written so it only depends on the parameters passed into it, that would be the most efficient. If not,Programming in Lua suggests that a closure be preferred to returning a table as the static variable and updating its members on each iteration.
ifexp1 thenblock1 elseifexp2 thenblock2 elseblock3 end
Executesblock1 ifexp1 returns true, otherwise executesblock2 ifexp2 returns true, andblock3 otherwise. Theelseblock3
portion may be omitted, and theelseifexp2 thenblock2
portion may be repeated or omitted as necessary.
returnexpression-list
The return statement is used to return values from a function or achunk (which is just a function). Theexpression-list is a comma-separated list of zero or more expressions.
Lua implementstail calls: ifexpression-list consists of exactly one expression which is a function call, the current stack frame will be reused for the call to that function. This has implication for functions that deal with the call stack, such asgetfenv()
anddebug.traceback()
.
The return statement must be the last statement in itsblock. If for some reason a return is needed in the middle of a block, an explicit blockdo return end
may be used.
break
The break statement is used to terminate the execution of a while, repeat, or for loop, skipping to the next statement after the loop.
The break statement must be the last statement in itsblock. If for some reason a break is needed in the middle of a block, an explicit blockdo break end
may be used.
Unlike some other languages, Lua does not have a "continue" statement for loops (i.e. a statement to move onto the next iteration without breaking the loop altogether).It is straightforward to achieve the same effect by nesting arepeat ... until true
block immediately inside the main loop, which will only ever iterate once for each iteration of the main loop (as its condition is always true).Usingbreak
will only end the inner loop, which has the practical effect of causing the main loop to continue onto the next iteration.If it is necessary to usebreak
on the main loop, simply declare a variable which is checked each time the inner loop completes, and set it when necessary.
A function call may be used as a statement; in this case, the function is being called only for any side effects it may have (e.g.mw.log() logs values) and any return values are discarded.
Lua provides syntactic sugar to make declaring a function and assigning it to a variable more natural. The following pairs of declarations are equivalent
-- Basic declarationfunction func(var-list )block endfunc = function (var-list )block end
-- Local functionlocal function func(var-list )block endlocal func; func = function (var-list )block end
-- Function as a field in a tablefunction table.func(var-list )block endtable.func = function (var-list )block end
-- Function as a method in a tablefunction table:func(var-list )block endtable.func = function ( self,var-list )block end
Note the colon notation here parallels the colon notation forfunction calls, adding an implicit argument namedself
at the beginning of the arguments list.
Errors may be "thrown" using theerror() andassert() functions. To "catch" errors, usepcall() orxpcall(). Note that certain internal Scribunto errors cannot be caught in Lua code.
Lua performs automatic memory management. This means that you have to worry neither about allocating memory for new objects nor about freeing it when the objects are no longer needed. Lua manages memory automatically by running agarbage collector from time to time to collect all dead objects (that is, objects that are no longer accessible from Lua) and objects that are only reachable viaweak references. All memory used by Lua is subject to automatic management: tables, functions, strings, etc.
Garbage collection happens automatically, and cannot be configured from within Scribunto.
The standard Lua libraries provide essential services and performance-critical functions to Lua. Only those portions of the standard libraries that are available in Scribunto are documented here.
This variable holds a reference to the current global variable table; the global variablefoo
may also be accessed as_G.foo
. Note, however, that there is nothing special about _G itself; it may be reassigned in the same manner as any other variable:
foo=1mw.log(foo)-- logs "1"_G.foo=2mw.log(foo)-- logs "2"_G={}-- _G no longer points to the global variable table_G.foo=3mw.log(foo)-- still logs "2"
The global variable table may be used just like any other table. For example,
-- Call a function whose name is stored in a variable_G[var]()-- Log the names and stringified values of all global variablesfork,vinpairs(_G)domw.log(k,v)end-- Log the creation of new global variablessetmetatable(_G,{__newindex=function(t,k,v)mw.log("Creation of new global variable '"..k.."'")rawset(t,k,v)end})
A string containing the running version of Lua, e.g. "Lua 5.1".
assert( v, message, ... )
Ifv
is nil or false, issues an error. In this case,message
is used as the text of the error: if nil (or unspecified), the text is "assertion failed!"; if a string or number, the text is that value; otherwise assert itself will raise an error.
Ifv
is any other value, assert returns all arguments includingv
andmessage
.
A somewhat common idiom in Lua is for a function to return a "true" value in normal operation, and on failure return nil or false as the first value and an error message as the second value. Easy error checking can then be implemented by wrapping the call in a call toassert
:
-- This doesn't check for errorslocalresult1,result2,etc=func(...)-- This works the same, but does check for errorslocalresult1,result2,etc=assert(func(...))
error( message, level )
Issues an error, with textmessage
.
error
normally adds some information about the location of the error. Iflevel
is 1 or omitted, that information is the location of the call toerror
itself; 2 uses the location of the call of the function that called error; and so on. Passing 0 omits inclusion of the location information.
getfenv( f )
Note this function may not be available, depending onallowEnvFuncs
in the engine configuration.
Returns anenvironment (global variable table), as specified byf
:
getfenv
. Often this will be the same as_G.The environments used by all standard library functions and Scribunto library functions are protected. Attempting to access these environments usinggetfenv
will return nil instead.
getmetatable( table )
Returns themetatable of atable. Any other type will return nil.
If the metatable has a__metatable
field, that value will be returned instead of the actual metatable.
ipairs( t )
Returns three values: an iterator function, the tablet
, and 0. This is intended for use in theiterator form offor
:
fori,vinipairs(t)do-- process each index-value pairend
This will iterate over the pairs ( 1, t[1] ), ( 2, t[2] ), and so on, stopping when t[i] would be nil.
The standard behavior may be overridden by providing an__ipairs
metamethod. If that metamethod exists, the call to ipairs will return the three values returned by__ipairs( t )
instead.
next( table, key )
This allows for iterating over the keys in a table. Ifkey
is nil or unspecified, returns the "first" key in the table and its value; otherwise, it returns the "next" key and its value. When no more keys are available, returns nil. It is possible to check whether a table is empty using the expressionnext( t ) == nil
.
Note that the order in which the keys are returned is not specified, even for tables with numeric indexes. To traverse a table in numerical order, use anumerical for oripairs.
Behavior is undefined if, when using next for traversal, any non-existing key is assigned a value. Assigning a new value (including nil) to an existing field is allowed.
pairs( t )
Returns three values: an iterator function (next or a work-alike), the tablet
, and nil. This is intended for use in theiterator form offor
:
fork,vinpairs(t)do-- process each key-value pairend
This will iterate over the key-value pairs int
just asnext would; see the documentation fornext for restrictions on modifying the table during traversal.
The standard behavior may be overridden by providing a __pairsmetamethod. If that metamethod exists, the call to pairs will return the three values returned by__pairs( t )
instead.
pcall( f, ... )
Calls the functionf
with the given arguments inprotected mode. This means that if an error is raised during the call tof
, pcall will return false and the error message raised. If no error occurs, pcall will return true and all values returned by the call.
Inpseudocode,pcall
might be defined something like this:
functionpcall(f,...)tryreturntrue,f(...)catch(message)returnfalse,messageendend
rawequal( a, b )
This is equivalent toa == b
except that it ignores any __eqmetamethod.
rawget( table, k )
This is equivalent totable[k]
except that it ignores any __indexmetamethod.
rawset( table, k, v )
This is equivalent totable[k] = v
except that it ignores any __newindexmetamethod.
select( index, ... )
Ifindex
is a number, returns all arguments in...
from that index onwards.Ifindex
is the string"#"
, returns the number of arguments in...
.
Note: unlike tables, lists of arguments (including thevararg expression...
) treatnil
as a distinct value (see documentation for# andunpack for the problem withnil
in tables). For example:
select(2,"foo","bar")
returns"bar"
.select(2,"foo",nil,"bar",nil)
returnsnil,"bar",nil
.select("#","foo","bar")
returns2
.select("#","foo","bar",nil)
returns3
.In other words,select
is roughly like the following (except that it also handles anynil
arguments after the final non-nil argument):
functionselect(index,...)localt={...}localmaxindex=table.maxn(t)ifindex=="#"thenreturnmaxindexelsereturnunpack(t,index,maxindex)endend
setmetatable( table, metatable )
Sets themetatable of atable.metatable
may be nil, but must be explicitly provided.
If the current metatable has a __metatable field,setmetatable
will throw an error.
Returnstable
.
tonumber( value, base )
Tries to convertvalue
to a number. If it is already a number or a string convertible to a number, thentonumber
returns this number; otherwise, it returns nil.
The optionalbase
(default 10) specifies the base to interpret the numeral. The base may be any integer between 2 and 36, inclusive. In bases above 10, the letter 'A' (in either upper or lower case) represents 10, 'B' represents 11, and so forth, with 'Z' representing 35.
In base 10, the value may have a decimal part, be expressed inE notation, and may have a leading "0x" to indicate base 16. In other bases, only unsigned integers are accepted.
tostring( value )
Convertsvalue
to a string. SeeData types above for details on how each type is converted.
The standard behavior for tables may be overridden by providing a __tostringmetamethod. If that metamethod exists, the call to tostring will return the single value returned by__tostring( value )
instead.
type( value )
Returns the type ofvalue
as a string:"nil"
,"number"
,"string"
,"boolean"
,"table"
, or"function"
.
unpack( table, i, j )
Returns values from the given table, something liketable[i], table[i+1], ···, table[j]
would do if written out manually. If nil or not given,i
defaults to 1 andj
defaults to#table
.
If the table does not have a value for a particular key, unpack will return nil for that value. For example,unpack({"foo",[3]="bar"},1,4)
returns"foo",nil,"bar",nil
.
Note that results are not deterministic iftable
is not asequence andj
is nil or unspecified; seeLength operator for details.
xpcall( f, errhandler )
This is much likepcall
, except that the error message is passed to the functionerrhandler
before being returned.However, unlikepcall
, no arguments may be given tof
.
Inpseudocode,xpcall
might be defined something like this:
functionxpcall(f,errhandler)tryreturntrue,f()catch(message)message=errhandler(message)returnfalse,messageendend
debug.traceback( message, level )
Returns a string with a traceback of the call stack. An optional message string is appended at the beginning of the traceback. An optional level number tells at which stack level to start the traceback.
math.abs( x )
Returns the absolute value ofx
.
math.acos( x )
Returns the arc cosine ofx
(given in radians).
math.asin( x )
Returns the arc sine ofx
(given in radians).
math.atan( x )
Returns the arc tangent ofx
(given in radians).
math.atan2( y, x )
Returns the arc tangent ofy/x
(given in radians), using the signs of both parameters to find the quadrant of the result.
math.ceil( x )
Returns the smallest integer larger than or equal tox
.
math.cos( x )
Returns the cosine ofx
(given in radians).
math.cosh( x )
Returns the hyperbolic cosine ofx
.
math.deg( x )
Returns the anglex
(given in radians) in degrees.
math.exp( x )
Returns the value.
math.floor( x )
Returns the largest integer smaller than or equal tox
.
math.fmod( x, y )
Returns the remainder of the division ofx
byy
that rounds the quotient towards zero. For example,math.fmod( 10, 3 )
yields1
.
math.frexp( x )
Returns two valuesm
ande
such that:
x
is finite and non-zero:,e
is an integer, and the absolute value ofm
is in the rangex
is zero:m
ande
are 0x
is NaN or infinite:m
isx
ande
is not specifiedThe value representing positive infinity; larger than or equal to any other numerical value.
math.ldexp( m, e )
Returns (e
should be an integer).
math.log( x )
Returns the natural logarithm ofx
.
math.log10( x )
Returns the base-10 logarithm ofx
.
math.max( x, ... )
Returns the maximum value among its arguments.
Behavior with NaNs is not specified. With the current implementation, NaN will be returned ifx
is NaN, but any other NaNs will be ignored.
math.min( x, ... )
Returns the minimum value among its arguments.
Behavior with NaNs is not specified. With the current implementation, NaN will be returned ifx
is NaN, but any other NaNs will be ignored.
math.modf( x )
Returns two numbers, the integral part ofx
and the fractional part ofx
. For example,math.modf( 1.25 )
yields1, 0.25
.
The value of.
math.pow( x, y )
Equivalent tox^y
.
math.rad( x )
Returns the anglex
(given in degrees) in radians.
math.random( m, n )
Returns a pseudo-random number.
The argumentsm
andn
may be omitted, but if specified must be convertible to integers.
Note that incorrect output may be produced ifm
orn
are less than −2147483648 or greater than 2147483647, or ifn - m
is greater than 2147483646.
math.randomseed( x )
Setsx
as theseed for the pseudo-random generator.
Note that using the same seed will causemath.random
to output the same sequence of numbers.
math.randomseed(tonumber(mw.getContentLanguage():formatDate("U"))*10000+os.clock()*10000)
math.sin( x )
Returns the sine ofx
(given in radians).
math.sinh( x )
Returns the hyperbolic sine ofx
.
math.sqrt( x )
Returns the square root ofx
. Equivalent tox^0.5
.
math.tan( x )
Returns the tangent ofx
(given in radians).
math.tanh( x )
Returns the hyperbolic tangent ofx
.
os.clock()
Returns an approximation of the amount in seconds of CPU time used by the program.
os.date( format, time )
Returns a string or a table containing date and time, formatted according toformat
. If the format is omitted or nil, "%c" is used.
Iftime
is given, it is the time to be formatted (seeos.time()
). Otherwise the current time is used.
Ifformat
starts with '!', then the date is formatted in UTC rather than the server's local time. After this optional character, if format is the string "*t", then date returns a table with the following fields:
If format is not "*t", then date returns the date as a string, formatted according to the same rules as the C functionstrftime.
os.difftime( t2, t1 )
Returns the number of seconds fromt1
tot2
.
os.time( table )
Returns a number representing the currentUnix time.
When called without arguments, returns the current time. If passed a table, the time encoded in the table will be parsed. The table must have the fields "year", "month", and "day", and may also include "hour" (default 12), "min" (default 0), "sec" (default 0), and "isdst".
require( modulename )
Loads the specified module.
First, it looks inpackage.loaded[modulename]
to see if the module is already loaded. If so, returnspackage.loaded[modulename]
.
Otherwise, it calls each loader in thepackage.loaders
sequence to attempt to find a loader for the module. If a loader is found, that loader is called. The value returned by the loader is stored intopackage.loaded[modulename]
and is returned.
See the documentation forpackage.loaders
for information on the loaders available.
For example, if you have a module "Module:Giving" containing the following:
localp={}p.someDataValue='Hello!'returnp
You can load this in another module with code such as this:
localgiving=require("Module:Giving")localvalue=giving.someDataValue-- value is now 'Hello!'
This table holds the loaded modules. The keys are the module names, and the values are the values returned when the module was loaded.
This table holds the sequence of searcher functions to use when loading modules. Each searcher function is called with a single argument, the name of the module to load. If the module is found, the searcher must return a function that will actually load the module and return the value to be returned byrequire. Otherwise, it must return nil.
Scribunto provides two searchers:
package.preload[modulename]
for the loader functionNote that the standard Lua loaders arenot included.
This table holds loader functions, used by the first searcher Scribunto includes inpackage.loaders.
package.seeall( table )
Sets the __indexmetamethod fortable
to_G.
In all string functions, the first character is at position 1, not position 0 as in C, PHP, and JavaScript. Indexes may be negative, in which case they count from the end of the string: position -1 is the last character in the string, -2 is the second-last, and so on.
Warning: The string library assumes one-byte character encodings.It cannot handle Unicode characters. To operate on Unicode strings, use the corresponding methods in theScribunto Ustring library.
string.byte( s, i, j )
If the string is considered as an array of bytes, returns the byte values fors[i]
,s[i+1]
, ···,s[j]
.The default value fori
is 1;the default value forj
is i
.Identical tomw.ustring.byte().
string.char( ... )
Receives zero or more integers. Returns a string with length equal to the number of arguments, in which each character has the byte value equal to its corresponding argument.
localvalue=string.char(0x48,0x65,0x6c,0x6c,0x6f,0x21)--value is now 'Hello!'
Seemw.ustring.char() for a similar function that uses Unicode codepoints rather than byte values.
string.find( s, pattern, init, plain )
Looks for the first match ofpattern
in the strings
. If it finds a match, thenfind
returns the offsets in s
where this occurrence starts and ends; otherwise, it returns nil. If the pattern has captures, then in a successful match the captured values are also returned after the two indices.
A third, optional numerical argumentinit
specifies where to start the search; its default value is 1 and can be negative. A value of true as a fourth, optional argumentplain
turns off the pattern matching facilities, so the function does a plain "find substring" operation, with no characters inpattern
being considered "magic".
Note that ifplain
is given, theninit
must be given as well.
Seemw.ustring.find() for a similar function extended as described inUstring patterns and where theinit
offset is in characters rather than bytes.
string.format( formatstring, ... )
Returns a formatted version of its variable number of arguments following the description given in its first argument (which must be a string).
The format string uses a limited subset of theprintf
format specifiers:
'-', '+', ' ', '#',
and'0'
.'*'
is not supported.'*'
is not supported.'c', 'd', 'i', 'o', 'u', 'x', 'X', 'e', 'E', 'f', 'g', 'G', 's', '%',
and the non-standard'q'
.The conversion specifierq
is likes
, but formats the string in a form suitable to be safely read back by the Lua interpreter: the string is written between double quotes, and all double quotes, newlines, embedded zeros, and backslashes in the string are correctly escaped when written.
Conversion between strings and numbers is performed as specified inData types; other types are not automatically converted to strings. Strings containing NUL characters (byte value 0) are not properly handled.
Identical tomw.ustring.format().
string.gmatch( s, pattern )
Returns an iterator function that, each time it is called, returns the next captures frompattern
over strings
. Ifpattern
specifies no captures, then the whole match is produced in each call.
For this function, a '^
' at the start of a pattern is not magic, as this would prevent the iteration. It is treated as a literal character.
Seemw.ustring.gmatch() for a similar function for which the pattern is extended as described inUstring patterns.
string.gsub( s, pattern, repl, n )
Returns two values:
s
in which all (or the firstn
, if given) occurrences of thepattern
have been replaced by a replacement string specified byrepl
, which can be a string, a table, or a function.Ifrepl
is a string or number, then its value is used for replacement. The character %
works as an escape character: any sequence inrepl
of the form%d
,withd between 1 and 9, stands for the value of thed-th captured substring. The sequence%0
stands for the whole match, and the sequence%%
stands for a single %
.
Ifrepl
is a table, then the table is queried for every match, using the first capture as the key; if the pattern specifies no captures, then the whole match is used as the key.
Ifrepl
is a function, then this function is called every time a match occurs, with all captured substrings passed as arguments, in order; if the pattern specifies no captures, then the whole match is passed as a sole argument.
If the value returned by the table query or by the function call is a string or a number, then it is used as the replacement string; otherwise, if it is false or nil, then there is no replacement (that is, the original match is kept in the string).
Seemw.ustring.gsub() for a similar function in which the pattern is extended as described inUstring patterns.
string.len( s )
Returns the length of the string, in bytes. Is not confused by ASCII NUL characters. Equivalent to#s
.
Seemw.ustring.len() for a similar function using Unicode codepoints rather than bytes.
string.lower( s )
Returns a copy of this string with all ASCII uppercase letters changed to lowercase. All other characters are left unchanged.
Seemw.ustring.lower() for a similar function in which all characters with uppercase to lowercase definitions in Unicode are converted.
string.match( s, pattern, init )
Looks for the first match ofpattern
in the string. If it finds one, thenmatch
returns the captures from the pattern; otherwise it returns nil. Ifpattern
specifies no captures, then the whole match is returned.
A third, optional numerical argumentinit
specifies where to start the search; its default value is 1 and can be negative.
Seemw.ustring.match() for a similar function in which the pattern is extended as described inUstring patterns and theinit
offset is in characters rather than bytes.
string.rep( s, n )
Returns a string that is the concatenation ofn
copies of the strings
. Identical tomw.ustring.rep().
string.reverse( s )
Returns a string that is the strings
reversed (bytewise).
string.sub( s, i, j )
Returns the substring ofs
that starts ati
and continues untilj
;i
andj
can be negative. Ifj
is nil or omitted, it will continue until the end of the string.
In particular, the callstring.sub(s,1,j)
returns a prefix ofs
with lengthj
, andstring.sub(s, -i)
returns a suffix ofs
with lengthi
.
Seemw.ustring.sub() for a similar function in which the offsets are characters rather than bytes.
string.ulower( s )
An alias formw.ustring.lower().
string.upper( s )
Returns a copy of this string with all ASCII lowercase letters changed to uppercase. All other characters are left unchanged.
Seemw.ustring.upper() for a similar function in which all characters with lowercase to uppercase definitions in Unicode are converted.
string.uupper( s )
An alias formw.ustring.upper().
Note that Lua's patterns are similar toregular expressions, but are not identical. In particular, note the following differences from regular expressions andPCRE:
%
), not backslash (\
)..
) always matches all characters, including newlines.|
operator).*
,+
,?
, and-
) may only be applied to individual characters or character classes, not to capture groups.-
, which is equivalent to PCRE's*?
quantifier.{n,m}
quantifier in PCRE).^
,$
, and the%f[set]
"frontier" pattern; assertions such as PCRE's\b
or(?=···)
are not present.\ddd
. However, since patterns arestrings these sort of escapes may be used in the string literals used to create the pattern-string.Also note that a pattern cannot contain embedded zero bytes (ASCII NUL,"\0"
). Use%z
instead.
Also seeUstring patterns for a similar pattern-matching scheme using Unicode characters.
Acharacter class is used to represent a set of characters. The following combinations are allowed in describing a character class:
x | (wherex is not one of the magic characters^$()%.[]*+-? ) represents the characterx itself. |
---|---|
. | (a dot) Represents all characters. |
%a | Represents all ASCII letters. |
%c | Represents all ASCII control characters. |
%d | Represents all digits. |
%l | Represents all ASCII lowercase letters. |
%p | Represents all punctuation characters. |
%s | Represents all ASCII space characters. |
%u | Represents all ASCII uppercase letters. |
%w | Represents all ASCII alphanumeric characters. Note it doesn't include the underscore character (_ ), contrarily to the usual class\w in regular expressions. |
%x | Represents all hexadecimal digits. |
%z | Represents ASCII NUL, the zero byte. |
%A | All characters not in%a . |
%C | All characters not in%c . |
%D | All characters not in%d . |
%L | All characters not in%l . |
%P | All characters not in%p . |
%S | All characters not in%s . |
%U | All characters not in%u . |
%W | All characters not in%w . |
%X | All characters not in%x . |
%Z | All characters not in%z . |
%y | (wherey is any non-alphanumeric character) represents the charactery . This is the standard way to escape the magic characters. Any punctuation character (even the non magic) can be preceded by a '% ' when used to represent itself in a pattern. |
[set] | Represents the class which is the union of all characters inset. A range of characters can be specified by separating the end characters of the range with a ' The interaction between ranges and classes is not defined. Therefore, patterns like |
[^set] | Represents the complement ofset, whereset is interpreted as above. |
Apattern item can be
*
', which matches 0 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;+
', which matches 1 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;-
', which also matches 0 or more repetitions of characters in the class. Unlike '*
', these repetition items will always match theshortest possible sequence;?
', which matches 0 or 1 occurrence of a character in the class;%n
, forn between 1 and 9; such item matches a substring equal to then-th captured string (see below);%bxy
, wherex andy are two distinct characters; such item matches strings that start with x, end with y, and where thex andy arebalanced. This means that, if one reads the string from left to right, counting +1 for anx and -1 for ay, the endingy is the firsty where the count reaches 0. For instance, the item%b()
matches expressions with balanced parentheses.%f[set]
, afrontier pattern; such item matches an empty string at any position such that the next character belongs toset and the previous character does not belong toset. The setset is interpreted as previously described. The beginning and the end of the subject are handled as if they were the character '\0'.Apattern is a sequence of pattern items.
A^
at the beginning of a pattern anchors the match at the beginning of the subject string. A$
at the end of a pattern anchors the match at the end of the subject string. At other positions,^
and$
have no special meaning and represent themselves.
A pattern can contain sub-patterns enclosed in parentheses; they describecaptures. When a match succeeds, the substrings of the subject string that match captures are stored ("captured") for future use. Captures are numbered according to their left parentheses. For instance, in the pattern(a*(.)%w(%s*))
, the part of the string matchinga*(.)%w(%s*)
is stored as the first capture (and therefore has number 1); the character matching.
is captured with number 2, and the part matching%s*
has number 3.
Capture references can appear in the pattern string itself, and refer back to text that was captured earlier in the match. For example,([a-z])%1
will match any pair of identical lowercase letters, while([a-z])([a-z])([a-z])[a-z]%3%2%1
will match any 7-letterpalindrome.
As a special case, the empty capture()
captures the current string position (a number). For instance, if we apply the pattern"()aa()"
on the string"flaaap"
, there will be two captures: 3 and 5.
Known limitations: UnlikeUstring library patterns, String library patterns may not contain more than 32 captures. If the pattern has more, then the String function will throw an error. Because the Ustring library has its own maximum of 10,000 bytes for patterns (unlike the String library), it is therefore impossible to use a pattern which exceeds both limits, as it will be incompatible with both libraries.
Most functions in the table library assume that the table represents asequence.
The functionstable.foreach()
,table.foreachi()
, andtable.getn()
may be available but are deprecated; use a for loop withpairs()
, a for loop withipairs()
, or thelength operator#
, respectively. The functiontable.setn()
is completely obsolete, however, and will throw an error if used.
table.concat( table, sep, i, j )
Given an array where all elements are strings or numbers, returnstable[i] .. sep .. table[i+1] ··· sep .. table[j]
.
The default value forsep
is an empty string, the default fori
is 1, and the default forj
is the length of the table. Ifi
is greater thanj
, it returns an empty string.
table.insert( table, value )
table.insert( table, pos, value )
Inserts elementvalue
at positionpos
intable
, shifting up other elements to open space, if necessary. The default value forpos
is the length of the table plus 1, so that a calltable.insert(t, x)
insertsx
at the end of tablet
.
Elements up to#table
are shifted; seeLength operator for caveats if the table is not asequence.
Note: when using thepos
parameter,value
should not benil
. Attempting to insert an explicitnil
value into the middle of a table will result in undefined behaviour, which may delete elements in the table unpredictably.
table.maxn( table )
Returns the largest positive numerical index of the given table, or zero if the table has no positive numerical indices.
To do this, it iterates over the whole table. This is roughly equivalent to
functiontable.maxn(table)localmaxn,k=0,nilrepeatk=next(table,k)iftype(k)=='number'andk>maxnthenmaxn=kenduntilnotkreturnmaxnend
table.remove( table, pos )
Removes fromtable
the element at positionpos
, shifting down other elements to close the space, if necessary. Returns the value of the removed element. The default value forpos
is the length of the table, so that a calltable.remove( t )
removes the last element of tablet
.
Elements up to#table
are shifted; seeLength operator for caveats if the table is not asequence.
table.sort( table, comp )
Sorts table elements in a given order,in-place, fromtable[1]
totable[#table]
.Ifcomp
is given, then it must be a function that receives two table elements, and returnstrue
when the first is less than the second (so thatnot comp(a[i+1],a[i])
will be true after the sort).Ifcomp
is not given, then the standard Lua operator<
is used instead.The sort algorithm is not stable; that is, elements considered equal by the given order may have their relative positions changed by the sort.
All Scribunto libraries are located in the tablemw
.
mw.addWarning( text )
Adds a warning which is displayed above the preview when previewing an edit.text
is parsed as wikitext.
mw.allToString( ... )
Callstostring() on all arguments, then concatenates them with tabs as separators.
mw.clone( value )
Creates a deep copy of a value. All tables (and their metatables) are reconstructed from scratch. Functions are still shared, however.
mw.getCurrentFrame()
Returns the currentframe object, typically the frame object from the most recent#invoke
.
mw.incrementExpensiveFunctionCount()
Adds one to the "expensive parser function" count, and throws an exception if it exceeds the limit (see$wgExpensiveParserFunctionLimit
).
mw.isSubsting()
Returns true if the current#invoke
is beingsubsted,false
otherwise. SeeReturning text above for discussion on differences when substing versus not substing.
mw.loadData( module )
Sometimes a module needs large tables of data; for example, a general-purpose module to convert units of measure might need a large table of recognized units and their conversion factors. And sometimes these modules will be used many times in one page. Parsing the large data table for every{{#invoke:}}
can use a significant amount of time. To avoid this issue,mw.loadData()
is provided.
mw.loadData
works likerequire()
, with the following differences:
{{#invoke:}}
call.package.loaded
.mw.loadData()
has metamethods that provide read-only access to the table returned by the module. Since it does not contain the data directly,pairs()
andipairs()
will work but other methods, including#value
,next()
, and the functions in theTable library, will not work correctly.The hypothetical unit-conversion module mentioned above might store its code in "Module:Convert" and its data in "Module:Convert/data", and "Module:Convert" would uselocal data = mw.loadData( 'Module:Convert/data' )
to efficiently load the data.
mw.loadJsonData( page )
This is the same asmw.loadData()
above, except it loads data from JSON pages rather than Lua tables.The JSON content must be an array or object.See alsomw.text.jsonDecode()
.
mw.dumpObject( object )
Serializesobject
to a human-readable representation, then returns the resulting string.
mw.log( ... )
Passes the arguments tomw.allToString(), then appends the resulting string to the log buffer.
When a Scribunto module is invoked on a page, the log buffer is included as "Lua logs" in the Parser profiling data, which is visible at the bottom of the page when previewing.It is also accessible via JavaScript aslimitreport-logs
, which is included in theScribunto
object inwgPageParseReport
frommw.config (i.e.mw.config.get("wgPageParseReport").scribunto["limitreport-logs"]
).
In the debug console, the functionprint()
is an alias for this function.
mw.logObject( object )
mw.logObject( object, prefix )
Callsmw.dumpObject() and appends the resulting string to the log buffer. Ifprefix
is given, it will be added to the log buffer followed by an equals sign before the serialized string is appended (i.e. the logged text will be "prefix = object-string").
The frame object is the interface to the parameters passed to{{#invoke:}}
, and to the parser.
Note that there is no frame library, and there is no global variable namedframe
. A frame object is typically obtained by being passed as a parameter to the function called by{{#invoke:}}
, and can also be obtained frommw.getCurrentFrame()
.
A table for accessing the arguments passed to the frame. For example, if a module is called from wikitext with
{{#invoke:module|function|arg1|arg2|name=arg3}}
thenframe.args[1]
will return"arg1"
,frame.args[2]
will return"arg2"
, andframe.args['name']
(orframe.args.name
) will return"arg3"
. It is also possible to iterate over arguments usingpairs(frame.args)
oripairs(frame.args)
.However, due to how Lua implements table iterators, iterating over arguments will return them in an unspecified order, and there's no way to know the original order as they appear in wikitext.
Note that values in this table are always strings;tonumber()
may be used to convert them to numbers, if necessary. Keys, however, are numbers even if explicitly supplied in the invocation:{{#invoke:module|function|1|2=2}}
gives string values"1"
and"2"
indexed by numeric keys1
and2
.
As in MediaWiki template invocations, named arguments will have leading and trailing whitespace removed from both the name and the value before they are passed to Lua, whereas unnamed arguments will not have whitespace stripped.
For performance reasons,frame.args
uses a metatable, rather than directly containing the arguments. Argument values are requested from MediaWiki on demand. This means that most other table methods will not work correctly, including#frame.args
,next( frame.args )
, and the functions in theTable library.
If preprocessor syntax such as template invocations and triple-brace arguments are included within an argument to#invoke
, they will not be expanded, after being passed to Lua, until their values are being requested in Lua. If certain special tags written in XML notation, such as<pre>
,<nowiki>
,<gallery>
and<ref>
, are included as arguments to#invoke
, then these tags will be converted to "strip markers" — special strings which begin with a delete character (ASCII 127), to be replaced with HTML after they are returned from #invoke.
frame:callParserFunction(name,args)
frame:callParserFunction(name,...)
frame:callParserFunction{name=string,args=table}
Call aparser function, returning an appropriate string. This is preferable toframe:preprocess
, but whenever possible, native Lua functions or Scribunto library functions should be preferred to this interface.
The following calls are approximately equivalent to the indicated wikitext:
-- {{ns:0}}frame:callParserFunction('ns',{0})frame:callParserFunction('ns',0)frame:callParserFunction{name='ns',args={0}}-- {{#tag:nowiki|some text}}frame:callParserFunction('#tag',{'nowiki','some text'})frame:callParserFunction('#tag','nowiki','some text')frame:callParserFunction('#tag:nowiki','some text')frame:callParserFunction{name='#tag',args={'nowiki','some text'}}-- {{#tag:ref|some text|name=foo|group=bar}}frame:callParserFunction('#tag',{'ref','some text',name='foo',group='bar'})
Note that, as withframe:expandTemplate(), the function name and arguments are not preprocessed before being passed to the parser function.
frame:expandTemplate{title=title,args=table}
This is transclusion. The call:
frame:expandTemplate{title='template',args={'arg1','arg2',name='arg3'}}
does roughly the same thing from Lua that{{template|arg1|arg2|name=arg3}}
does in wikitext. As in transclusion, if the passed title does not contain a namespace prefix it will be assumed to be in the Template: namespace.
Note that the title and arguments are not preprocessed before being passed into the template:
-- This is roughly equivalent to wikitext like {{template|{{!}}}}frame:expandTemplate{title='template',args={'|'}}-- This is roughly equivalent to wikitext like {{template|{{((}}!{{))}}}}frame:expandTemplate{title='template',args={'{{!}}'}}
frame:extensionTag(name,content,args)
frame:extensionTag{name=string,content=string,args=table_or_string}
This is equivalent to a call toframe:callParserFunction() with function name'#tag'
(seeHelp:Magic words#Miscellaneous) and withname
andcontent
prepended toargs
.
-- These are equivalentframe:extensionTag('ref','some text',{name='foo',group='bar'})frame:extensionTag{name='ref',content='some text',args={name='foo',group='bar'}}frame:callParserFunction('#tag',{'ref','some text',name='foo',group='bar'})-- These are equivalentframe:extensionTag{name='ref',content='some text',args={'some other text'}}frame:callParserFunction('#tag',{'ref','some text','some other text'})
frame:getParent()
Called on the frame created by{{#invoke:}}
, returns the frame for the page that called{{#invoke:}}
. Called on that frame, returns nil.
For instance, if the template{{Example}}
contains the code{{#invoke:ModuleName|FunctionName|A|B}}
, and a page transcludes that template with the code{{Example|C|D}}
, then inModule:ModuleName, callingframe.args[1]
andframe.args[2]
returns"A"
and"B"
, and callingframe:getParent().args[1]
andframe:getParent().args[2]
returns"C"
and"D"
, withframe
being the first argument in the function call.
frame:getTitle()
Returns the title associated with the frame as a string. For the frame created by{{#invoke:}}
, this is the title of the module invoked.
frame:newChild{title=title,args=table}
Create a newFrame object that is a child of the current frame, with optional arguments and title.
This is mainly intended for use in providing a specific parent frame environment for calls likeframe:newChild(...):callParserFunction('#invoke',...)
orframe:newChild(...):preprocess(...)
, etc., for modules that check their parent frame, etc.Beyond casual debugging, e.g., testing functions in the debug console, etc., it should not be used to attempt to emulate{{#invoke:}}
in production code as there are a number of ways the called module can detect how it is called.The number of frames that may be created at any one time is limited.
frame:preprocess(string)
frame:preprocess{text=string}
This expands wikitext in the context of the frame, i.e. templates, parser functions, and parameters such as{{{1}}}
are expanded, and returns the expanded text. Certain special tags written in XML-style notation, such as<pre>
,<nowiki>
,<gallery>
and<ref>
, will be replaced with "strip markers" — special strings which begin with a delete character (ASCII 127), to be replaced with HTML after they are returned from#invoke
.
If you are expanding a single template, useframe:expandTemplate
instead of trying to construct a wikitext string to pass to this method. It's faster and less prone to error if the arguments contain pipe characters or other wikimarkup.
If you are expanding a single parser function, useframe:callParserFunction
for the same reasons.
frame:getArgument(arg)
frame:getArgument{name=arg}
Gets an object for the specified argument, or nil if the argument is not provided.
The returned object has one method,object:expand()
, that returns the expanded wikitext for the argument.
frame:newParserValue(text)
frame:newParserValue{text=text}
Returns an object with one method,object:expand()
, that returns the result offrame:preprocess( text )
.
frame:newTemplateParserValue{title=title,args=table}
Returns an object with one method,object:expand()
, that returns the result offrame:expandTemplate
called with the given arguments.
frame:argumentPairs()
Same aspairs(frame.args)
. Included for backwards compatibility.
mw.hash.hashValue( algo, value )
Hashes a string value with the specified algorithm. Valid algorithms may be fetched usingmw.hash.listAlgorithms().
mw.hash.listAlgorithms()
Returns a list of supported hashing algorithms, for use inmw.hash.hashValue().
mw.html
is a fluent interface for building complex HTML from Lua. On many Wikimedia wikis this was formerly implemented inModule:HtmlBuilder
. A mw.html object can be created usingmw.html.create
.
Functions documented asmw.html.name
are available on the globalmw.html
table; functions documented asmw.html:name
andhtml:name
are methods of an mw.html object (seemw.html.create
).
A basic example could look like this:
localdiv=mw.html.create('div')div:attr('id','testdiv'):css('width','100%'):wikitext('Some text'):tag('hr')returntostring(div)-- Output: <div>Some text<hr /></div>
mw.html.create( tagName, args )
Creates a new mw.html object containing atagName
html element. You can also pass an empty string or nil astagName
in order to create an empty mw.html object.
args
can be a table with the following keys:
args.selfClosing
: Force the current tag to be self-closing, even if mw.html doesn't recognize it as self-closingargs.parent
: Parent of the current mw.html instance (intended for internal usage)html:node( builder )
Appends a child mw.html (builder
) node to the current mw.html instance. If a nil parameter is passed, this is a no-op. A (builder
) node is a string representation of an html element.
html:wikitext( ... )
Appends an undetermined number of wikitext strings to the mw.html object.
Note that this stops at the firstnil item.
Basic wikitext will get parsed, like HTML, links, bold, lists or tables. However, templates and parser functions won't be evaluated if they are passed directly to this function, unless they came from template parameters.Those will be rendered in plain text instead.To evaluate them, they'll have to be passed throughframe:preprocess.
html:newline()
Appends a newline to the mw.html object.Useful when used before and aftermw.html:wikitext(), when the wikitext contains lists or tables, whose syntax only has a special meaning when present at the start of a line.
html:tag( tagName, args )
Appends a new child node with the giventagName
to the builder, and returns a mw.html instance representing that new node. Theargs
parameter is identical to that ofmw.html.create
Note that contrarily to other methods such ashtml:node()
, this method doesn't return the current mw.html instance, but the mw.html instance of the newly inserted tag.Make sure to usehtml:done()
to go up to the parent mw.html instance, orhtml:allDone()
if you have nested tags on several levels.
html:attr( name, value )
html:attr( table )
Set an HTML attribute with the givenname
andvalue
on the node. Alternatively a table holding name->value pairs of attributes to set can be passed. In the first form, a value of nil causes any attribute with the given name to be unset if it was previously set.
html:getAttr( name )
Get the value of a html attribute previously set usinghtml:attr()
with the givenname
.
html:addClass( class )
Adds a class name to the node's class attribute. If a nil parameter is passed, this is a no-op.
html:css( name, value )
html:css( table )
Set a CSS property with the givenname
andvalue
on the node. Alternatively a table holding name->value pairs of properties to set can be passed. In the first form, a value of nil causes any property with the given name to be unset if it was previously set.
html:cssText( css )
Add some rawcss
to the node's style attribute. If a nil parameter is passed, this is a no-op.
html:done()
Returns the parent node under which the current node was created. Like jQuery.end, this is a convenience function to allow the construction of several child nodes to be chained together into a single statement.
html:allDone()
Likehtml:done()
, but traverses all the way to the root node of the tree and returns it.
Language codes are described atlanguage code. Many of MediaWiki's language codes are similar toIETF language tags, but not all MediaWiki language codes are valid IETF tags or vice versa.
Functions documented asmw.language.name
are available on the globalmw.language
table; functions documented asmw.language:name
andlang:name
are methods of a language object (seemw.language.new
ormw.language.getContentLanguage
).
mw.language.fetchLanguageName( code, inLanguage )
The full name of the language for the given language code: native name (language autonym) by default, name translated in target language if a value is given forinLanguage.
mw.language.fetchLanguageNames()
mw.language.fetchLanguageNames( inLanguage )
mw.language.fetchLanguageNames( inLanguage, include )
Fetch the list of languages known to MediaWiki, returning a table mapping language code to language name.
By default the name returned is the language autonym; passing a language code forinLanguage returns all names in that language.
By default, only language names known to MediaWiki are returned; passing'all'
forinclude will return all available languages (fromExtension:CLDR), while passing'mwfile'
will include only languages having customized messages included with MediaWiki core or enabled extensions. To explicitly select the default,'mw'
may be passed.
mw.language.getContentLanguage()
mw.getContentLanguage()
Returns a new language object for the wiki's default content language.
mw.language.getFallbacksFor( code )
Returns a list of MediaWiki's fallback language codes for the specified code.
mw.language.isKnownLanguageTag( code )
Returnstrue
if a language code is known to MediaWiki.
A language code is "known" if it is a "valid built-in code" (i.e. it returnstrue
formw.language.isValidBuiltInCode
) and returns a non-empty string formw.language.fetchLanguageName
.
mw.language.isSupportedLanguage( code )
Checks whether any localisation is available for that language code in MediaWiki.
A language code is "supported" if it is a "valid" code (returnstrue
formw.language.isValidCode
), contains no uppercase letters, and has a message file in the currently-running version of MediaWiki.
It is possible for a language code to be "supported" but not "known" (i.e. returningtrue
formw.language.isKnownLanguageTag
). Also note that certain codes are "supported" despitemw.language.isValidBuiltInCode
returningfalse
.
mw.language.isValidBuiltInCode( code )
Returnstrue
if a language code is of a valid form for the purposes of internal customisation of MediaWiki.
The code may not actually correspond to any known language.
A language code is a "valid built-in code" if it is a "valid" code (i.e. it returnstrue
formw.language.isValidCode
); consists of only ASCII letters, numbers, and hyphens; and is at least two characters long.
Note that some codes are "supported" (i.e. returningtrue
frommw.language.isSupportedLanguage
) even though this function returnsfalse
.
mw.language.isValidCode( code )
Returnstrue
if a language code string is of a valid form, whether or not it exists. This includes codes which are used solely for customisation via the MediaWiki namespace.
The code may not actually correspond to any known language.
A language code is valid if it does not contain certain unsafe characters (colons, single- or double-quotes, slashs, backslashs, angle brackets, ampersands, or ASCII NULs) and is otherwise allowed in a page title.
mw.language.new( code )
mw.getLanguage( code )
Creates a new language object. Language objects do not have any publicly accessible properties, but they do have several methods, which are documented below.
There is a limit of 200 on the number of distinct language codes that may be used on a page. Exceeding this limit will result in errors.
lang:getCode()
Returns the language code for this language object.
lang:toBcp47Code()
Returns the standardBCP-47 language code for this language object. This is the code string which is appropriate to use in HTML, for example as the value of alang
attribute.
lang:getFallbackLanguages()
Returns a list of MediaWiki's fallback language codes for this language object. Equivalent tomw.language.getFallbacksFor( lang:getCode() )
.
lang:isRTL()
Returnstrue
if the language is written right-to-left,false
if it is written left-to-right.
lang:lc( s )
Converts the string to lowercase, honoring any special rules for the given language.
When theUstring library is loaded, themw.ustring.lower() function is implemented as a call tomw.language.getContentLanguage():lc( s )
.
lang:lcfirst( s )
Converts the first character of the string to lowercase, as withlang:lc()
.
lang:uc( s )
Converts the string to uppercase, honoring any special rules for the given language.
When theUstring library is loaded, themw.ustring.upper()
function is implemented as a call tomw.language.getContentLanguage():uc( s )
.
lang:ucfirst( s )
Converts the first character of the string to uppercase, as withlang:uc().
lang:caseFold( s )
Converts the string to a representation appropriate for case-insensitive comparison. Note that the result may not make any sense when displayed.
lang:formatNum( n )
lang:formatNum( n, options )
Formats a number with grouping and decimal separators appropriate for the given language. Given 123456.78, this may produce "123,456.78", "123.456,78", or even something like "١٢٣٬٤٥٦٫٧٨" depending on the language and wiki configuration.
Theoptions
is a table of options, which can be:
noCommafy
: Settrue
to omit grouping separators and use a dot (.
) as the decimal separator. Digit transformation may still occur, which may include transforming the decimal separator.lang:formatDate( format, timestamp, local )
Formats a date according to the given format string. Iftimestamp
is omitted, the default is the current time. The value forlocal
must be a boolean or nil; iftrue
, the time is formatted in thewiki's local time rather than in UTC.
The format string and supported values fortimestamp
are identical to those for the#time parser function fromExtension:ParserFunctions.Note however that backslashes may need to be doubled in a Lua string literal, since Lua also uses backslash as an escape character while wikitext does not:
-- This string literal contains a newline, not the two characters "\n", so it is not equivalent to {{#time:\n}}.lang:formatDate('\n')-- This is equivalent to {{#time:\n}}, not {{#time:\\n}}.lang:formatDate('\\n')-- This is equivalent to {{#time:\\n}}, not {{#time:\\\\n}}.lang:formatDate('\\\\n')
lang:formatDuration( seconds )
lang:formatDuration( seconds, chosenIntervals )
Breaks a duration in seconds into more human-readable units, e.g. 12345 to 3 hours, 25 minutes and 45 seconds, returning the result as a string.
chosenIntervals
, if given, is a table with values naming the interval units to use in the response. These include 'millennia
', 'centuries
', 'decades
', 'years
', 'weeks
', 'days
', 'hours
', 'minutes
', and 'seconds
'.
lang:parseFormattedNumber( s )
This takes a number as formatted bylang:formatNum() and returns the actual number. In other words, this is basically a language-aware version oftonumber()
.
lang:convertPlural( n, ... )
lang:convertPlural( n, forms )
lang:plural( n, ... )
lang:plural( n, forms )
This chooses the appropriate grammatical form fromforms
(which must be asequence table) or...
based on the numbern
. For example, in English you might usen .. ' ' .. lang:plural( n, 'sock', 'socks' )
orn .. ' ' .. lang:plural( n, { 'sock', 'socks' } )
to generate grammatically-correct text whether there is only 1 sock or 200 socks.
The necessary values for the sequence are language-dependent, seelocalization of magic words andtranslatewiki's FAQ on PLURAL for some details.
lang:convertGrammar( word, case )
lang:grammar( case, word )
convertGrammar
matches the order of the method of the same name on MediaWiki's Language object, whilegrammar
matches the order of the parser function of the same name, documented atHelp:Magic words#Localisation.This chooses the appropriate inflected form ofword
for the given inflection codecase
.
The possible values forword
andcase
are language-dependent, seeSpecial:MyLanguage/Help:Magic words#Localisation andtranslatewiki:Grammar for some details.
lang:gender( what, masculine, feminine, neutral )
lang:gender( what, { masculine, feminine, neutral } )
Chooses the string corresponding to the gender ofwhat
, which may be "male", "female", or a registered user name.
lang:getArrow( direction )
Returns a Unicode arrow character corresponding todirection
:
lang:getDir()
Returns "ltr" or "rtl", depending on the directionality of the language.
lang:getDirMark( opposite )
Returns a string containing either U+200E (the left-to-right mark) or U+200F (the right-to-left mark), depending on the directionality of the language and whetheropposite
is a true or false value.
lang:getDirMarkEntity( opposite )
Returns "‎" or "‏", depending on the directionality of the language and whetheropposite
is a true or false value.
lang:getDurationIntervals( seconds )
lang:getDurationIntervals( seconds, chosenIntervals )
Breaks a duration in seconds into more human-readable units, e.g. 12345 to 3 hours, 25 minutes and 45 seconds, returning the result as a table mapping unit names to numbers.
chosenIntervals
, if given, is a table with values naming the interval units to use in the response. These include 'millennia
', 'centuries
', 'decades
', 'years
', 'weeks
', 'days
', 'hours
', 'minutes
', and 'seconds
'.
Those unit keywords are also the keys used in the response table. Only units with a non-zero value are set in the response, unless the response would be empty in which case the smallest unit is returned with a value of 0.
This library is an interface to the localisation messages and the MediaWiki: namespace.
Functions documented asmw.message.name
are available on the globalmw.message
table; functions documented asmw.message:name
andmsg:name
are methods of a message object (seemw.message.new
).
mw.message.new( key, ... )
Creates a new message object for the given messagekey
.The remaining parameters are passed to the new object'sparams()
method.
The message object has no properties, but has several methods documented below.
mw.message.newFallbackSequence( ... )
Creates a new message object for the given messages (the first one that exists will be used).
The message object has no properties, but has several methods documented below.
mw.message.newRawMessage( msg, ... )
Creates a new message object, using the given text directly rather than looking up an internationalized message. The remaining parameters are passed to the new object'sparams()
method.
The message object has no properties, but has several methods documented below.
mw.message.rawParam( value )
Wraps the value so that it will not be parsed as wikitext.
mw.message.numParam( value )
Wraps the value so that it will automatically be formatted as bylang:formatNum()
. Note this does not depend on theLanguage library actually being available.
mw.message.getDefaultLanguage()
Returns a Language object for the default language.
msg:params( ... )
msg:params( params )
Add parameters to the message, which may be passed as individual arguments or as asequence table. Parameters must be numbers, strings, or the special values returned bymw.message.numParam() ormw.message.rawParam(). If a sequence table is used, parameters must be directly present in the table; references using the__index metamethod will not work.
Returns themsg
object, to allow for call chaining.
msg:rawParams( ... )
msg:rawParams( params )
Like:params(), but has the effect of passing all the parameters throughmw.message.rawParam() first.
Returns themsg
object, to allow for call chaining.
msg:numParams( ... )
msg:numParams( params )
Like:params(), but has the effect of passing all the parameters throughmw.message.numParam() first.
Returns themsg
object, to allow for call chaining.
msg:inLanguage( lang )
Specifies the language to use when processing the message.lang
may be a string or a table with agetCode()
method (i.e. aLanguage object).
The default language is the one returned bymw.message.getDefaultLanguage()
.
Returns themsg
object, to allow for call chaining.
msg:useDatabase( bool )
Specifies whether to look up messages in the MediaWiki: namespace (i.e. look in the database), or just use the default messages distributed with MediaWiki.
The default istrue
.
Returns themsg
object, to allow for call chaining.
msg:plain()
Substitutes the parameters and returns the message wikitext as-is. Template calls and parser functions are intact.
msg:exists()
Returns a boolean indicating whether the message key exists.
msg:isBlank()
Returns a boolean indicating whether the message key has content. Returnstrue
if the message key does not exist or the message is the empty string.
msg:isDisabled()
Returns a boolean indicating whether the message key is disabled. Returnstrue
if the message key does not exist or if the message is the empty string or the string "-".
A string holding the current version of MediaWiki.
The value of$wgScriptPath
.
The value of$wgServer
.
The value of$wgSitename
.
The value of$wgStylePath
.
Table holding data for all namespaces, indexed by number.
The data available is:
A metatable is also set that allows for looking up namespaces by name (localized or canonical). For example, bothmw.site.namespaces[4]
andmw.site.namespaces.Project
will return information about the Project namespace.
Table holding just the content namespaces, indexed by number. Seemw.site.namespaces for details.
Table holding just the subject namespaces, indexed by number. Seemw.site.namespaces for details.
Table holding just the talk namespaces, indexed by number. Seemw.site.namespaces for details.
Table holding site statistics. Available statistics are:
mw.site.stats.pagesInCategory( category, which )
Gets statistics about the category. Ifwhich
has the special value "*
", the result is a table with the following properties:
Ifwhich
is one of the above keys ("all", "subcats", "files", "pages"), the result is a number with the corresponding value.
Each new category queried will increment the expensive function count.
mw.site.stats.pagesInNamespace( namespace )
Returns the number of pages in the given namespace (specify by number).
mw.site.stats.usersInGroup( group )
Returns the number of users in the given group.
mw.site.interwikiMap( filter )
Returns a table holding data about availableinterwiki prefixes. Iffilter
is the string "local", then only data for local interwiki prefixes is returned. Iffilter
is the string "!local", then only data for non-local prefixes is returned. If no filter is specified, data for all prefixes is returned. A "local" prefix in this context is one that is for the same project. For example, on the English Wikipedia, other-language Wikipedias are considered local, while Wiktionary and such are not.
Keys in the table returned by this function are interwiki prefixes, and the values are subtables with the following properties:
$wgExtraInterlanguageLinkPrefixes
.The text library provides some common text processing functions missing from theString library and theUstring library. These functions are safe for use with UTF-8 strings.
mw.text.decode( string )
mw.text.decode( string, decodeNamedEntities )
ReplacesHTML entities in the string with the corresponding characters.
If booleandecodeNamedEntities
is omitted or false, the only named entities recognized are<
(<),>
(>),&
(&),"
(") and
(the non-breaking space, U+00A0).Otherwise, the list of HTML5 named entities to recognize is loaded from PHP'sget_html_translation_table
function.
Known bugs: Approximately 600 of around 2,200 named entities in the HTML5 standard do not get decoded, even whendecodeNamedEntities
is used; this includes approximately 40 of around 250 entities which are also included in HTML4.This occurs because PHP'sget_html_translation_table
function returns only one mapping for each character, so for example
is not decoded since PHP returns only→
as the mapping for→
.→
mw.text.encode( string )
mw.text.encode( string, charset )
Replaces characters in a string withHTML entities.Five characters are replaced with the appropriate named entities:<
,>
,&
,"
and the non-breaking space (U+00A0).All others are replaced with numeric entities.
Ifcharset
is supplied, it should be a string as appropriate to go inside brackets in aUstring pattern, i.e. the "set" in[set]
. The default charset contains six characters:<
,>
,&
,"
,'
and the non-breaking space (U+00A0).
mw.text.jsonDecode( string )
mw.text.jsonDecode( string, flags )
Decodes a JSON string.flags
is 0 or a combination (use+
) of the flagsmw.text.JSON_PRESERVE_KEYS
andmw.text.JSON_TRY_FIXING
.
Normally JSON's zero-based arrays are renumbered to Lua one-based sequence tables; to prevent this, passmw.text.JSON_PRESERVE_KEYS
.
To relax certain requirements in JSON, such as no terminal comma in arrays or objects, passmw.text.JSON_TRY_FIXING
. This is not recommended.
Limitations:
mw.text.JSON_PRESERVE_KEYS
is used.mw.text.jsonEncode( value )
mw.text.jsonEncode( value, flags )
Encode a JSON string. Errors are raised if the passed value cannot be encoded in JSON.flags
is 0 or a combination (use+
) of the flagsmw.text.JSON_PRESERVE_KEYS
andmw.text.JSON_PRETTY
.
Normally Lua one-based sequence tables are encoded as JSON zero-based arrays; whenmw.text.JSON_PRESERVE_KEYS
is set inflags
, zero-based sequence tables are encoded as JSON arrays.
Limitations:
[]
), not empty objects ({}
).__pairs
metamethod is required.mw.text.JSON_PRESERVE_KEYS
is used.mw.text.killMarkers( string )
Removes all MediaWikistrip markers from a string.
mw.text.listToText( list )
mw.text.listToText( list, separator, conjunction )
Joins a list, prose-style. In other words, it's liketable.concat()
but with a different separator before the final item.
The default separator is taken fromMediaWiki:comma-separator in the wiki's content language, and the default conjunction isMediaWiki:and concatenated withMediaWiki:word-separator.
Examples, using the default values for the messages:
-- Returns the empty stringmw.text.listToText({})-- Returns "1"mw.text.listToText({1})-- Returns "1 and 2"mw.text.listToText({1,2})-- Returns "1, 2, 3, 4 and 5"mw.text.listToText({1,2,3,4,5})-- Returns "1; 2; 3; 4 or 5"mw.text.listToText({1,2,3,4,5},'; ',' or ')
mw.text.nowiki( string )
Replaces various characters in the string withHTML entities to prevent their interpretation as wikitext. This includes:
"
,&
,'
,<
,=
,>
,[
,]
,{
,|
,}
#
,*
,:
,;
, space, tab (\t
)----
at the start of the string or immediately after a newline will have the first-
escaped__
will have one underscore escaped://
will have the colon escapedISBN
,RFC
, orPMID
will be escapedmw.text.split( string, pattern, plain )
Splits the string into substrings at boundaries matching theUstring patternpattern
. Ifplain
is specified andtrue
,pattern
will be interpreted as a literal string rather than as a Lua pattern (just as with the parameter of the same name formw.ustring.find()
). Returns a table containing the substrings.
For example,mw.text.split( 'a b\tc\nd', '%s' )
would return a table{ 'a', 'b', 'c', 'd' }
.
Ifpattern
matches the empty string,string
will be split into individual characters.
Note that this function can be over 60 times slower than a reimplementation that is not Unicode-aware, such as the following:
functionsplit(text,pattern,plain)localret={}locals,l=1,string.len(text)whilesdolocale,n=string.find(text,pattern,s,plain)ifnotethenret[#ret+1]=string.sub(text,s)s=nilelseifn<ethen-- Empty separator!ret[#ret+1]=string.sub(text,s,e)ife<lthens=e+1elses=nilendelseret[#ret+1]=e>sandstring.sub(text,s,e-1)or''s=n+1endendreturnretend
mw.text.gsplit( string, pattern, plain )
Returns aniterator function that will iterate over the substrings that would be returned by the equivalent call tomw.text.split()
.
Note that this function can be over 60 times slower than a reimplementation that is not Unicode-aware, such as the following:
functiongsplit(text,pattern,plain)locals,l=1,string.len(text)returnfunction()ifsthenlocale,n=string.find(text,pattern,s,plain)localretifnotethenret=string.sub(text,s)s=nilelseifn<ethen-- Empty separator!ret=string.sub(text,s,e)ife<lthens=e+1elses=nilendelseret=e>sandstring.sub(text,s,e-1)or''s=n+1endreturnretendend,nil,nilend
mw.text.tag( name, attrs, content )
mw.text.tag{ name = string, attrs = table, content = string|false }
Generates an HTML-style tag forname
.
Ifattrs
is given, it must be a table with string keys. String and number values are used as the value of the attribute; booleantrue
results in the key being output as an HTML5 valueless parameter; booleanfalse
skips the key entirely; and anything else is an error.
Ifcontent
is not given (or is nil), only the opening tag is returned. Ifcontent
is booleanfalse
, a self-closed tag is returned. Otherwise it must be a string or number, in which case that content is enclosed in the constructed opening and closing tag. Note the content is not automatically HTML-encoded; usemw.text.encode() if needed.
For properly returning extension tags such as<ref>
, useframe:extensionTag() instead.
mw.text.trim( string )
mw.text.trim( string, charset )
Remove whitespace or other characters from the beginning and end of a string.
Ifcharset
is supplied, it should be a string as appropriate to go inside brackets in aUstring pattern, i.e. the "set" in[set]
. The default charset is ASCII whitespace,%s
, which is equivalent to"\t\r\n\f\v "
.
mw.text.truncate( text, length )
mw.text.truncate( text, length, ellipsis )
mw.text.truncate( text, length, ellipsis, adjustLength )
Truncatestext
to the specified length in code points, addingellipsis
if truncation was performed. If length is positive, the end of the string will be truncated; if negative, the beginning will be removed. IfadjustLength
is given andtrue
, the resulting string including ellipsis will not be longer than the specified length.
The default value forellipsis
is taken fromMediaWiki:ellipsis in the wiki's content language.
Examples, using the default "..." ellipsis:
-- Returns "foobarbaz"mw.text.truncate("foobarbaz",9)-- Returns "fooba..."mw.text.truncate("foobarbaz",5)-- Returns "...arbaz"mw.text.truncate("foobarbaz",-5)-- Returns "foo..."mw.text.truncate("foobarbaz",6,nil,true)-- Returns "foobarbaz", because that's shorter than "foobarba..."mw.text.truncate("foobarbaz",8)
mw.text.unstripNoWiki( string )
Replaces MediaWiki <nowiki>strip markers with the corresponding text. Other types of strip markers are not changed.
mw.text.unstrip( string )
Equivalent tomw.text.killMarkers( mw.text.unstripNoWiki( string ))
.
This no longer reveals the HTML behind special page transclusion, <ref> tags, and so on as it did in earlier versions of Scribunto.
mw.title.equals( a, b )
Test for whether two titles are equal. Note that fragments are ignored in the comparison.
mw.title.compare( a, b )
Returns -1, 0, or 1 to indicate whether the titlea
is less than, equal to, or greater than titleb
.
This compares titles by interwiki prefix (if any) as strings, then by namespace number, then by the unprefixed title text as a string. These string comparisons use Lua's standard<
operator.
mw.title.getCurrentTitle()
Returns the title object for the current page.
mw.title.new( text, namespace )
mw.title.new( ID )
Creates a new title object.
If a numberID
is given, an object is created for the title with that page_id. The title referenced will be counted as linked from the current page. If the page_id does not exist, returns nil. The expensive function count will be incremented if the title object created is not for a title that has already been loaded.
If a stringtext
is given instead, an object is created for that title (even if the page does not exist). If the text string does not specify a namespace,namespace
(which may be any key found inmw.site.namespaces
) will be used. If the text is not a valid title, nil is returned.
mw.title.makeTitle( namespace, title, fragment, interwiki )
Creates a title object with titletitle
in namespacenamespace
, optionally with the specifiedfragment
andinterwiki
prefix.namespace
may be any key found inmw.site.namespaces
. If the resulting title is not valid, returns nil.
Note that, unlikemw.title.new()
, this method will always apply the specified namespace. For example,mw.title.makeTitle( 'Template', 'Module:Foo' )
will create an object for the page Template:Module:Foo, whilemw.title.new( 'Module:Foo', 'Template' )
will create an object for the page Module:Foo.
Note also that functionality for interwiki titles is limited tointerwiki
/isExternal
/isLocal
and URL-related methods; other methods might not behave as expected.
A title object has a number of properties and methods. Most of the properties are read-only.
Note that fields ending withtext
return titles as string values whereas the fields ending withtitle
return title objects.
0
if the page does not exist.Thismay be expensive.nil
if this title cannot have a talk page.(added in MediaWiki 1.42.0-wmf.15, refsT180911)title.text
.title.text
.title.text
.file.exists
for Media-namespace titles. For File-namespace titles this checks the existence of the file description page, not the file itself.Thismay be expensive.mw.site.namespaces
.mw.site.namespaces
.mw.site.namespaces
.mw.title.makeTitle( title.namespace, title.baseText )
.mw.title.makeTitle( title.namespace, title.rootText )
.mw.title.makeTitle( mw.site.namespaces[title.namespace].talk.id, title.text )
, ornil
if this title cannot have a talk page.mw.title.makeTitle( mw.site.namespaces[title.namespace].subject.id, title.text )
.false
otherwise."edit"
and"move"
). The table values are arrays, the first item of which is a string containing the protection level. If the page is unprotected, either the table values or the array items will benil
.This isexpensive."restrictions"
(itself a table with keys likeprotectionLevels
has) and"sources"
(an array listing titles where the protections cascade from). If no protections cascade to the page,"restrictions"
and"sources"
will be empty.This isexpensive.mw.title.makeTitle( title.namespace, title.text .. '/' ..text )
.title.text
encoded as it would be in a URL."http"
,"https"
,"relative"
(the default), or"canonical"
.nil
if there is no page. The page will be recorded as a transclusion.A few properties are also added by extensions:
Title objects may be compared usingrelational operators.tostring( title )
will returntitle.prefixedText
.
Note that accessing anyexpensive field on a title object records a "link" to the page (as shown onSpecial:WhatLinksHere, for example). Using the title object'sgetContent()
method or accessing theredirectTarget
field records it asfile
orfileExists
fields records it as a "file link".
Title objects representing a page in the File or Media namespace will have a property calledfile
.This isexpensive. This is a table, structured as follows:
fileExists
property on a Title object exists for backwards compatibility reasons and is an alias for this property. If this isfalse
, all other file properties will benil
.nil
. The# operator can be used to get the number of pages in the file. Each individual page table contains a width and height property.The propertiesid
,isRedirect
,exists
, andcontentModel
require fetching data about the title from the database. For this reason, theexpensive function count is incremented the first time one of them is accessed for a page other than the current page. Subsequent accesses of any of these properties for that page will not increment the expensive function count again.
Other properties marked as expensive will always increment the expensive function count the first time they are accessed for a page other than the current page.
mw.uri.encode( string, enctype )
Percent-encodes the string. The default type,"QUERY"
, encodes spaces using '+' for use in query strings;"PATH"
encodes spaces as %20; and"WIKI"
encodes spaces as '_'.
Note that the "WIKI" format is not entirely reversible, as both spaces and underscores are encoded as '_'.
mw.uri.decode( string, enctype )
Percent-decodes the string. The default type,"QUERY"
, decodes '+' to space;"PATH"
does not perform any extra decoding; and"WIKI"
decodes '_' to space.
mw.uri.anchorEncode( string )
Encodes a string for use in a MediaWiki URI fragment.
mw.uri.buildQueryString( table )
Encodes a table as a URI query string. Keys should be strings; values may be strings or numbers, sequence tables, or boolean false.
mw.uri.parseQueryString( s, i, j )
Decodes the query strings
to a table. Keys in the string without values will have a value offalse
; keys repeated multiple times will have sequence tables as values; and others will have strings as values.
The optional numerical argumentsi
andj
can be used to specify a substring ofs
to be parsed, rather than the entire string.i
is the position of the first character of the substring, and defaults to 1.j
is the position of the last character of the substring, and defaults to the length of the string. Bothi
andj
can be negative, as instring.sub.
mw.uri.canonicalUrl( page, query )
Returns aURI object for thecanonical URL for a page, with optional query string/table.
mw.uri.fullUrl( page, query )
Returns aURI object for thefull URL for a page, with optional query string/table.
mw.uri.localUrl( page, query )
Returns aURI object for thelocal URL for a page, with optional query string/table.
mw.uri.new( string )
Constructs a newURI object for the passed string or table. See the description of URI objects for the possible fields for the table.
mw.uri.validate( table )
Validates the passed table (or URI object). Returns a boolean indicating whether the table was valid, and on failure a string explaining what problems were found.
The URI object has the following fields, some or all of which may be nil:
The following properties are also available:
tostring()
will give the URI string.
Methods of the URI object are:
uri:parse( string )
Parses a string into the current URI object. Any fields specified in the string will be replaced in the current object; fields not specified will keep their old values.
uri:clone()
Makes a copy of the URI object.
uri:extend( parameters )
Merges the parameters table into the object's query table.
The ustring library is intended to be a direct reimplementation of the standardString library, except that the methods operate on characters in UTF-8 encoded strings rather than bytes.
Most functions will raise an error if the string is not valid UTF-8; exceptions are noted.
The maximum allowed length of a pattern, in bytes.
The maximum allowed length of a string, in bytes.
mw.ustring.byte( s, i, j )
Returns individual bytes; identical tostring.byte().
mw.ustring.byteoffset( s, l, i )
Returns the byte offset of a character in the string. The default for bothl
andi
is 1.i
may be negative, in which case it counts from the end of the string.
The character atl
== 1 is the first character starting at or after bytei
; the character atl
== 0 is the first character starting at or before bytei
. Note this may be the same character. Greater or lesser values ofl
are calculated relative to these.
mw.ustring.char( ... )
Much likestring.char(), except that the integers are Unicode codepoints rather than byte values.
localvalue=mw.ustring.char(0x41f,0x440,0x438,0x432,0x435,0x442,0x21)-- value is now 'Привет!'
mw.ustring.codepoint( s, i, j )
Much likestring.byte(), except that the return values are codepoints and the offsets are characters rather than bytes.
mw.ustring.find( s, pattern, init, plain )
Much likestring.find(), except that the pattern is extended as described inUstring patterns and theinit
offset is in characters rather than bytes.
mw.ustring.format( format, ... )
Identical tostring.format(). Widths and precisions for strings are expressed in bytes, not codepoints.
mw.ustring.gcodepoint( s, i, j )
Returns three values for iterating over the codepoints in the string.i
defaults to 1, andj
to -1. This is intended for use in theiterator form offor
:
forcodepointinmw.ustring.gcodepoint(s)do-- blockend
mw.ustring.gmatch( s, pattern )
Much likestring.gmatch(), except that the pattern is extended as described inUstring patterns.
Known bug - When used with a pattern which can match the empty string, the function will get stuck in an infinite loop. For example, the following loop never terminates:
forcaptureinmw.ustring.gmatch("foo bar",".*")do-- blockend
mw.ustring.gsub( s, pattern, repl, n )
Much likestring.gsub(), except that the pattern is extended as described inUstring patterns.
Known bugs: Whenrepl
is a table, it is possible to use numbers as keys instead of strings (e.g. to replace instances of
in a string, the value at key"5"
or[5]
would be used); as such, the output is not predictable if they have different (non-nil) values.This is not an issue forstring.gsub(), which ignores any numbers as keys.["5"]
mw.ustring.isutf8( string )
Returnstrue
if the string is valid UTF-8,false
if not.
mw.ustring.len( string )
Returns the length of the string in codepoints, or nil if the string is not valid UTF-8.
Seestring.len() for a similar function that uses byte length rather than codepoints.
mw.ustring.lower( string )
Much likestring.lower(), except that all characters with lowercase to uppercase definitions in Unicode are converted.
If theLanguage library is also loaded, this will instead calllc() on the default language object.
mw.ustring.match( s, pattern, init )
Much likestring.match(), except that the pattern is extended as described inUstring patterns and theinit
offset is in characters rather than bytes.
mw.ustring.rep( string, n )
Identical tostring.rep().
mw.ustring.sub( s, i, j )
Much likestring.sub(), except that the offsets are characters rather than bytes.
mw.ustring.toNFC( string )
Converts the string toNormalization Form C (also known as Normalization Form Canonical Composition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFD( s )
Converts the string toNormalization Form D (also known as Normalization Form Canonical Decomposition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFKC( s )
Converts the string toNormalization Form KC (also known as Normalization Form Compatibility Composition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFKD( s )
Converts the string toNormalization Form KD (also known as Normalization Form Compatibility Decomposition). Returns nil if the string is not valid UTF-8.
mw.ustring.upper( s )
Much likestring.upper(), except that all characters with uppercase to lowercase definitions in Unicode are converted.
If theLanguage library is also loaded, this will instead calluc() on the default language object.
Patterns in the ustring functions use the same syntax as theString library patterns. The major difference is that the character classes are redefined in terms ofUnicode character properties:
%a
: represents all characters with General Category "Letter".%c
: represents all characters with General Category "Control".%d
: represents all characters with General Category "Number, decimal digit".%l
: represents all characters with General Category "Lowercase Letter".%p
: represents all characters with General Category "Punctuation".%s
: represents all characters with General Category "Separator", plus tab, linefeed, carriage return, vertical tab, and form feed.%u
: represents all characters with General Category "Uppercase Letter".%w
: represents all characters with General Category "Letter" or "Decimal Number".%x
: adds fullwidth character versions of the hex digits.Like inString library patterns,%A
,%C
,%D
,%L
,%P
,%S
,%U
,%W
and%X
here represent the complementary set ("all characterswithout given General Category").
In all cases, characters are interpreted as Unicode characters instead of bytes, so ranges such as[0-9]
, patterns such as%b«»
, and quantifiers applied to multibyte characters will work correctly. Empty captures will capture the position in code points rather than bytes.
Known limitations: UnlikeString library patterns, Ustring library patterns have a maximum length of 10,000 bytes. If the pattern exceeds this length, then the Ustring function will throw an error. Because the String library has its own maximum of 32 captures (unlike the Ustring library), it is therefore impossible to use a pattern which exceeds both limits, as it will be incompatible with both libraries.
Note: 9 ASCII characters,$
,+
,<
,=
,>
,^
,`
,|
,~
, can be matched by%p
in the string library but not in the ustring library, as Unicode classifies them as Symbols rather than Punctuation.
These libraries are not included by default, but if needed may be loaded usingrequire()
.
This emulation of the Lua 5.2bit32
library may be loaded using:
bit32=require('bit32')
The bit32 library providesbitwise operations on unsigned 32-bit integers. Input numbers are truncated to integers (in an unspecified manner) and reduced modulo 232 so the value is in the range 0 to 232−1; return values are also in this range.
When bits are numbered (as inbit32.extract()), 0 is the least-significant bit (the one with value 20) and 31 is the most-significant (the one with value 231).
bit32.band( ... )
Returns thebitwise AND of its arguments: the result has a bit set only if that bit is set in all of the arguments.
If given zero arguments, the result has all bits set.
bit32.bnot( x )
Returns thebitwise complement ofx
.
bit32.bor( ... )
Returns thebitwise OR of its arguments: the result has a bit set if that bit is set in any of the arguments.
If given zero arguments, the result has all bits clear.
bit32.btest( ... )
Equivalent tobit32.band( ... ) ~= 0
bit32.bxor( ... )
Returns thebitwise XOR of its arguments: the result has a bit set if that bit is set in an odd number of the arguments.
If given zero arguments, the result has all bits clear.
bit32.extract( n, field, width )
Extractswidth
bits fromn
, starting with bitfield
. Accessing bits outside of the range 0 to 31 is an error.
If not specified, the default forwidth
is 1.
bit32.replace( n, v, field, width )
Replaceswidth
bits inn
, starting with bitfield
, with the lowwidth
bits fromv
. Accessing bits outside of the range 0 to 31 is an error.
If not specified, the default forwidth
is 1.
bit32.lshift( n, disp )
Returns the numbern
shifteddisp
bits to the left. This is alogical shift: inserted bits are 0. This is generally equivalent to multiplying by 2disp
.
Note that a displacement over 31 will result in 0.
bit32.rshift( n, disp )
Returns the numbern
shifteddisp
bits to the right. This is alogical shift: inserted bits are 0. This is generally equivalent to dividing by 2disp
.
Note that a displacement over 31 will result in 0.
bit32.arshift( n, disp )
Returns the numbern
shifteddisp
bits to the right. This is anarithmetic shift: ifdisp
is positive, the inserted bits will be the same as bit 31 in the original number.
Note that a displacement over 31 will result in 0 or 4294967295.
bit32.lrotate( n, disp )
Returns the numbern
rotateddisp
bits to the left.
Note that rotations are equivalent modulo 32: a rotation of 32 is the same as a rotation of 0, 33 is the same as 1, and so on.
bit32.rrotate( n, disp )
Returns the numbern
rotateddisp
bits to the right.
Note that rotations are equivalent modulo 32: a rotation of 32 is the same as a rotation of 0, 33 is the same as 1, and so on.
This library contains methods useful when implementing Scribunto libraries. It may be loaded using:
libraryUtil=require('libraryUtil')
libraryUtil.checkType( name, argIdx, arg, expectType, nilOk )
Raises an error iftype( arg )
does not matchexpectType
. In addition, no error will be raised ifarg
is nil andnilOk
is true.
name
is the name of the calling function, andargIdx
is the position of the argument in the argument list. These are used in formatting the error message.
libraryUtil.checkTypeMulti( name, argIdx, arg, expectTypes )
Raises an error iftype( arg )
does not match any of the strings in the arrayexpectTypes
.
This is for arguments that have more than one valid type.
libraryUtil.checkTypeForIndex( index, value, expectType )
Raises an error iftype( value )
does not matchexpectType
.
This is intended for use in implementing a__newindex
metamethod.
libraryUtil.checkTypeForNamedArg( name, argName, arg, expectType, nilOk )
Raises an error iftype( arg )
does not matchexpectType
. In addition, no error will be raised ifarg
is nil andnilOk
is true.
This is intended to be used as an equivalent tolibraryUtil.checkType()
in methods called using Lua's "named argument" syntax,func{ name = value }
.
libraryUtil.makeCheckSelfFunction( libraryName, varName, selfObj, selfObjDesc )
This is intended for use in implementing "methods" on object tables that are intended to be called with theobj:method()
syntax. It returns a function that should be called at the top of these methods with theself
argument and the method name, which will raise an error if thatself
object is notselfObj
.
This function will generally be used in a library's constructor function, something like this:
functionmyLibrary.new()localobj={}localcheckSelf=libraryUtil.makeCheckSelfFunction('myLibrary','obj',obj,'myLibrary object')functionobj:method()checkSelf(self,'method')endfunctionobj:method2()checkSelf(self,'method2')endreturnobjend
Theluabit library modules "bit" and "hex" may be loaded using:
bit=require('luabit.bit')hex=require('luabit.hex')
Note that thebit32 library contains the same operations as "luabit.bit", and the operations in "luabit.hex" may be performed usingstring.format()
andtonumber()
.
The luabit module "noki" is not available, as it is entirely useless in Scribunto. The luabit module "utf8" is also not available, as it was considered redundant to theUstring library.
Thestrict library is not a normal library; it causes an error to be raised whenever a new variable is used that is not explicitly scoped as a local variable (e.g., global variable assignment references). This functionality is typically enabled by loading at the top of a module using:
require('strict')
On many Wikimedia wikis this was formerly implemented inModule:No globals
, which was replaced viaphab:T209310. It is in part derived fromstrict.lua.
The pure-Lua backend to theUstring library may be loaded using:
ustring=require('ustring')
In all cases the Ustring library (mw.ustring
) should be used instead, as that replaces many of the slower and more memory-intensive operations with callbacks into PHP code.
Some MediaWiki extensions provide additional Scribunto libraries. These are also located in the tablemw
, usually in the tablemw.ext
, however, they are only present when certain extensions are installed (in addition to the Scribunto extension itself).
Such extensions use Scribunto provided hooks:
Writing Scribunto libraries provides information on how such libraries can be developed to provide Lua interfaces for MediaWiki extensions.
Wikibase Client provides access to localizable structured data, most notablyWikidata.Seedocs_topics_lua.html andExtension:Wikibase Client/Lua.
WikibaseLexeme provides access to Wikibase Lexeme entities. This is supported byWikidata:Lexicographical data.Seedocs_topics_lua.html andExtension:WikibaseLexeme/Lua.
WikibaseMediaInfo provides access to Wikibase MediaInfo entities.SeeWikibaseMediaInfo/Lua.This is supported byStructured Data on Commons. SeeStructured data/Lua.
BCmath provides arbitrary-precision arithmetic to Lua modules. See BCmath documentation via "LDoc" link atExtension:BCmath.
Semantic Scribunto provides native Scribunto support for theSemantic MediaWiki extension.
JsonConfig provides access to localizable tabular and map data.SeeJsonConfig/Tabular.Tabular Data and GeoJSONMap Data is supported in the "Data:" namespace at Commons.
mw.ext.data.get(pagename )
Cargo provides a means to query its data store from Lua.SeeExtension:Cargo/Other features#Lua support.
CategoryToolbox provides a means to check from Lua if a certain page belongs to a category.It is experimental and not enabled on public Wikimedia wikis. But the "categories"field of the title object does the same work and is enabled.
FlaggedRevs provides a means to access the stability settings of a page from Lua.
TitleBlacklist provides a means to test and obtain information about blacklisted page naming entries from Lua.
[EXPERIMENTAL] Part of theTranslate extension. Provides a means to query translations present insidemessage bundles. Readmodule documentation for more information.
ParserFunctions provides a means from Lua to evaluate expressions in the same way as its PHP-based parser function#expr
.
Proofread Page provides access to Index and Page namespaces.SeeExtension:Proofread Page/Lua reference.This is supported byWikisource:ProofreadPage.SeeHelp:Extension:ProofreadPage.
ArticlePlaceholder provides a means to override default Wikibase renderings from Lua.SeeExtension:ArticlePlaceholder/Module:AboutTopic.
ExternalData provides a means to get structured data from the Internet from Lua.SeeExtension:External Data/Lua.
mw.ext.UnlinkedWikibase.getEntity(id )
mw.ext.UnlinkedWikibase.query(sparql )
WikiSEO provides a means to set SEO Data for the current page. SeeWikiSEO#Usage in lua modules.
WSSlots provides a number of Lua functions for working withMCR slots:
mw.slots.slotContent(slotName,pageName)
mw.slots.slotTemplates(slotName,pageName)
(deprecated)mw.slots.slotContentModel(slotName,pageName)
mw.slots.slotData(slotName,pageName)
TabberNeue provides a means to render a Tabber from Lua.SeeExtension:TabberNeue#Lua for usage.
The following functions have beenmodified:
The following packages aremostly removed. Only those functions listed are available:
The following functions and packages arenot available:
{{#invoke:}}
and passing such data structures as parameters to Scribunto library functions that are implemented as callbacks into PHP.mw.loadData()
.This information is useful to developers writing additional Scribunto libraries, whether for inclusion in Scribunto itself or for providing an interface for their own extensions.
A Scribunto library will generally consist of five parts:
Existing libraries serve as a good example.
The PHP portion of the library is a class that must extendScribunto_LuaLibraryBase
. See the documentation for that class for implementation details. In the Scribunto extension, this file should be placed inengines/LuaCommon/NameLibrary.php
, and a mapping added toScribunto_LuaEngine::$libraryClasses
. Other extensions should use theScribuntoExternalLibraries hook. In either case, the key should match the Lua module name ("mw.name" for libraries in Scribunto, or "mw.ext.name" for extension libraries).
The Lua portion of the library sets up the table containing the functions that can be called from Lua modules. In the Scribunto extension, the file should be placed inengines/LuaCommon/lualib/mw.name.lua
. This file should generally include boilerplate something like this:
localobject={}localphpfunctionobject.setupInterface(options)-- Remove setup functionobject.setupInterface=nil-- Copy the PHP callbacks to a local variable, and remove the globalphp=mw_interfacemw_interface=nil-- Do any other setup here-- Install into the mw globalmw=mwor{}mw.ext=mw.extor{}mw.ext.NAME=object-- Indicate that we're loadedpackage.loaded['mw.ext.NAME']=objectendreturnobject
The module inengines/LuaCommon/lualib/libraryUtil.lua
(load this withlocal util = require 'libraryUtil'
) contains some functions that may be helpful.
Be sure to run the Scribunto test cases with your library loaded, even if your library doesn't itself provide any test cases. The standard test cases include tests for things like libraries adding unexpected global variables. Also, if the library is loaded with PHP, any upvalues that its Lua functions have will not be reset between #invoke's. Care must be taken to ensure that modules can't abuse this to transfer information between #invoke's.
The Scribunto extension includes a base class for test cases,Scribunto_LuaEngineTestBase
, which will run the tests against both theLuaSandbox andLuaStandalone engines.The library's test case should extend this class, and should not overridestatic function suite()
.In the Scribunto extension, the test case should be intests/engines/LuaCommon/NameLibraryTest.php
and added to the array inScribuntoHooks::unitTestsList()
(incommon/Hooks.php
); extensions should add the test case in their ownUnitTestsList
hook function, probably conditional on whether$wgAutoloadClasses['Scribunto_LuaEngineTestBase']
is set.
Most of the time, all that is needed to make the test case is this:
class''ClassName''TestextendsScribunto_LuaEngineTestBase{protectedstatic$moduleName='<i>ClassName</i>Test';functiongetTestModules(){returnparent::getTestModules()+array('<i>ClassName</i>Test'=>__DIR__.'/<i>ClassName</i>Tests.lua';);}}
This will load the fileClassNameTests.lua
as if it were the page "Module:ClassNameTests", expecting it to return an object with the following properties:
n
, the name of testn
, and a string that is the expected output for testn
.n
and returns one string.IfgetTestModules()
is declared as shown, "Module:TestFramework" is available which provides many useful helper methods. If this is used,ClassNameTests.lua
would look something like this:
localtestframework=require'Module:TestFramework'returntestframework.getTestProvider({-- Tests go here})
Each test is itself a table, with the following properties:
The type controls the format ofexpect
and howfunc
is called. Included types are:
expect
is a table of return values, or a string if the test should raise an error.func
is simply called.expect
is a table of tables of return values.func
is called as with aniteratedfor loop, and each iteration's return values are accumulated.tostring()
.There are (at least) two ways to run PHPUnit tests:
--filter
option may be used to run only your extension's tests.Either of these will work fine if Scribunto is loaded in LocalSettings.php. And it is easy for method #1 to work if Scribunto is not loaded, as the UnitTestsList hook can easily be written to avoid returning the Scribunto test when$wgAutoloadClasses['Scribunto_LuaEngineTestBase']
is not set.
ButJenkins uses method #2. For Jenkins to properly run the tests, you will need to add Scribunto as a dependency for your extension. SeeGerrit change 56570 for an example of how this is done.
If for some reason you need the tests to be able to run using method #2 without Scribunto loaded, one workaround is to add this check to the top of your unit test file:
if(!isset($GLOBALS['wgAutoloadClasses']['Scribunto_LuaEngineTestBase'])){return;}
Modules included in Scribunto should include documentation in theScribunto libraries section above. Extension libraries should include documentation in a subpage of their own extension page, and link to that documentation from theExtension libraries subsection above.
This manual is derived from theLua 5.1 reference manual, which is available under theMIT license.
Copyright © 1994–2012 Lua.org, PUC-Rio. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. This derivative manual may also be copied under the terms of the same license. |