Extension:Scribunto/Lua reference manual: Difference between revisions
→frame.args: + note on number versus string keys and values in frame.args |
→frame.args: minor tweak |
||
Line 1,433: | Line 1,433: | ||
==== frame.args ==== |
==== frame.args ==== |
||
A table for accessing the arguments passed to the frame. For example, if |
A table for accessing the arguments passed to the frame. For example, if a module is called from wikitext with |
||
<nowiki>{{#invoke:module|function|arg1|arg2|name=arg3}}</nowiki> |
<nowiki>{{#invoke:module|function|arg1|arg2|name=arg3}}</nowiki> |
||
Line 1,439: | Line 1,439: | ||
then <code>frame.args[1]</code> will return "arg1", <code>frame.args[2]</code> will return "arg2", and <code>frame.args['name']</code> (or <code>frame.args.name</code>) will return "arg3". It is also possible to iterate over arguments using <code style="white-space:nowrap">pairs( frame.args )</code> or <code style="white-space:nowrap">ipairs( frame.args )</code>. |
then <code>frame.args[1]</code> will return "arg1", <code>frame.args[2]</code> will return "arg2", and <code>frame.args['name']</code> (or <code>frame.args.name</code>) will return "arg3". It is also possible to iterate over arguments using <code style="white-space:nowrap">pairs( frame.args )</code> or <code style="white-space:nowrap">ipairs( frame.args )</code>. |
||
Note that values in this table are always strings; <code>[[#tonumber|tonumber()]]</code> may be used to convert them to numbers, if necessary. Keys, however, are numbers even if explicitly supplied in the invocation: <nowiki>{{#invoke:module|function|1|2=2}}</nowiki> |
Note that values in this table are always strings; <code>[[#tonumber|tonumber()]]</code> may be used to convert them to numbers, if necessary. Keys, however, are numbers even if explicitly supplied in the invocation: <nowiki>{{#invoke:module|function|1|2=2}}</nowiki> gives string values "1" and "2" indexed by numeric keys 1 and 2. |
||
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. |
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. |
Revision as of 07:19, 19 February 2013
Introduction
This manual documents Lua as it is used in MediaWiki with the Scribunto extension. Some parts are derived from the Lua 5.1 reference manual, which is available under an MIT-style 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.
Getting started
On a MediaWiki wiki with Lua enabled, create a page with a title starting with "Module:", for example "Module:Bananas". Into this new page, copy the following text:
local p = {}
function p.hello()
return "Hello, world!"
end
return p
Save that, then on another (non-module) 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!"
Lua language
Tokens
Names (also called identifiers) 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:
- #
- %
- (
- )
- *
- +
- ,
- -
- .
- ..
- ...
- /
- :
- ;
- <
- <=
- =
- ==
- >
- >=
- [
- ]
- ^
- {
- }
- ~=
Comments
A comment starts with a --
anywhere outside a string. If the --
is immediately followed by an opening long bracket, the comment continues to the corresponding closing long bracket; otherwise the comment runs to the end of the current line.
Data types
Lua is a dynamically-typed language, which means that varibles 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. The type()
function will return the type of a value.
The tostring()
function will convert a value to a string. The tonumber()
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 by tonumber()
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
"Nil" is the data type of nil
, 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.
boolean
Boolean values are true
and false
.
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, only false and nil are considered false for boolean conversion; the number 0 and the empty string are both considered true.
string
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 JavaScrpit and unlike PHP, there is no difference between the two. The following escape sequences are recognized: '\a' (bell), '\b' (backspace), '\f' (form feed), '\n' (newline), '\r' (carriage return), '\t' (horizontal tab), '\v' (vertical tab), '\\' (backslash), '\"' (double quote), and '\'' (single quote). A literal newline may also be included in a string by preceeding it with a backslash. Bytes may also be specified using an escape sequence '\ddd', where ddd is the decimal value of the byte in the range 0–255. To include Unicode characters using escape sequences, the individual bytes for the UTF-8 encoding must be specified; in general, it will be more straightforward to enter the Unicode characters directly.
Literal strings can also be defined using long 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 ]=====]
. Strings delimited by long brackets do not interpret escape sequences. As a special case, if an opening long bracket is immediately followed by a newline then the newline is not included in the string.
-- This long string
foo = [[
bar\tbaz
]]
-- Is equivalent to this normal string
bar = '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.
number
Lua has only one numeric type, which is typically represented internally as a double-precision floating-point value. In this format, integers between -9007199254740992 and 9007199254740992 may be represented exactly, while higher and lower numbers will suffer from round-off error.
Numbers are specified using a period (.
) as a decimal separator and without grouping separators, e.g. 123456.78
. Numbers may also be represented using E notation without spaces, e.g. 1.23e-10
, 123.45e20
, or 1.23E5
. Integers may also be specified in hexidecimal notation using a 0x
prefix, e.g. 0x3A
.
Although NaN and positive and negative infinities are correctly stored and handled, Lua does not provide corresponding literals. The constant math.huge
is positive infinity, as is a division such as 1/0
, and a division such as 0/0
may be used to quickly generate a NaN.
Note that all numbers are considered true when converted to boolean. This is unlike most other languages, where the number 0 is usually considered false. When converted to a string, finite numbers are represented in decimal, possibly in E notation; NaN is "nan" or "-nan"; and infinities are "inf" or "-inf".
table
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 of expression1 as the key and the (first) value of expression2 as the value.name = expression
is equivalent to["name"] = expression
expression
is roughly equivalent to[i] = expression
, where i 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 valid names may also be accessed using dot notation, e.g. table.key
is equivalent to table['key']
. Calling a function that is a value in the table may use colon notation, e.g. table:func( ... )
, which is equivalent to table['func']( table, ... )
.
A sequence 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 sequences, and ignore non-positive-integer keys.
Unlike PHP or JavaScript, however, 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 table
t = {}
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 above
t2 = {
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.
function
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 the function
keyword, and called using parentheses. Syntactic sugar is available for named functions, local functions, and functions that act like member functions to a table. See Function declarations and Function calls below for details.
Lua functions are closures, 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".
Unsupported types
The userdata 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.
The thread type represents the handles for coroutines, which are not available in Scribunto's sandbox.
Metatables
Every table may have an associated table known as a metatable. 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 the getmetatable() function, and set with the setmetatable() function.
When being accessed for their meta functions, metatable fields are accessed as if with rawget().
Metatable fields that affect the table itself are:
- __index
- This is used when a table access
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 )
. The rawget() function bypasses this metamethod. - __newindex
- This is used when assigning a key to a table
t[key] = value
whererawget( t, key )
would return nil. If the value of this field is a table, the assignment will be repeated in that table, 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 )
. The rawset() function bypasses this metamethod. - __call
- This is used when function call syntax is used on a table,
t( ··· )
. The value must be a function, which is called as something like__call( t, ··· )
. - __mode
- This is used to make tables holding weak references. The value must be a string. By default, any value that is used as a key or as a value in a table will not be garbage collected. But if this metafield contains the letter 'k', keys may be garbage collected if there are no non-weak references, and if it contains 'v' values may be; in either case, both the corresponding key and value are removed from the table. Note that behavior is undefined if this field is altered after the table is used as a metatable.
Other metatable fields include:
Note: In Lua, all strings also share a single metatable, in which __index refers to the string
table. This metatable is not accessible in Scribunto, nor is the referenced string
table; the string table available to modules is a copy.
Variables
Variables are places that store values. There are three kinds of variables in Lua: global variables, local variables, and table fields.
A name 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 the local
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 an environment; 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 the getfenv() function and changed using the setfenv() function; in Scribunto, these functions are severely restricted if they are available at all.
Expressions
An expression is something that has values: literals (numbers, strings, true, false, nil), anonymous function declarations, table constructors, variable references, function calls, the vararg 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.
Arithmetic operators
Lua supports the usual arithmetic operators: addition, subtraction, multiplication, division, modulo, exponentiation, and negation.
When all operands are numbers or strings for which tonumber() returns non-nil, the operations have their usual meaning.
If either operand is a table with an appropriate metamethod, 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 as a % b == a - math.floor( a / b ) * b
|
^ | Exponentiation | a ^ b | __pow | non-integer exponents are allowed |
- | Negation | -a | __unm |
Relational operators
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 __eq metamethod.
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 __lta <= 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.
Logical operators
The logical operators are and
, or
, and not
. All use the standard interpretation where nil and false are considered false and anything else is considered true.
For and
, if the left operand is considered false then it is returned and the second operand is not evaluated; othewise the second operand is returned.
For or
, if the left operand is considered true then it is returned and the second operand is not evaluated; othewise the second operand is returned.
For not
, the result is always true or false.
Note that and
and or
short circuit. For example, foo() or bar()
will only call bar()
if foo()
returns false or nil as its first value.
Concatenation operator
The concatenation operator is two dots, used as a .. b
. If both operands are numbers or strings, they are converted to strings and concatenated. Otherwise if a __concat metamethod 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 does a = 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 use string.format() or to insert all the strings into a sequence and use table.concat() at the end.
Length operator
The length operator is #
, used as #a
. If a
is a string, it returns the length in bytes. If a
is a sequence table, it returns the length of the sequence.
If a
is a table that is not a sequence, the #a
may return any value N such that a[N] is not nil and a[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 )
Operator precedence
Lua's operator precedence, 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 as a ^ (b ^ c)
.
Function calls
Lua function calls look like those in most other languages: a name followed by a list of arguments in parentheses:
func( exp-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; see Function declataions 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( exp-list )
is exactly equivalent to
table.name( table, exp-list )
The second common case is Lua's method of implementing named 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 } )
Function declarations
The syntax for function declaraion looks like this:
function ( var-list ) block end
All variables in var-list are local to the function, with values assigned from the expression list in the function call. Additional local variables may be declared inside the block.
When the function is called, the statements in block are executed after local variables corresponding to var-list are created and assigned values. If a return 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 are lexical 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 argument function makeAdder( n ) return function( x ) -- The variable n from the outer scope is available here to be added to x return x + n end end local add5 = 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 the var-list:
function ( var-list, ... ) block end
Within the block, the varargs expression ...
may be used, with the result being all the extra values in the function call. For example,
local join = function ( separator, ... ) -- get the extra arguments as a table local args = { ... } -- get the count of extra arguments, correctly local n = select( '#', ... ) return table.concat( args, sep, 1, n ) end join( ', ', 'foo', 'bar', baz' ) -- returns the string "foo, bar, baz"
The select() 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.
Lua provides syntactic sugar to combine function declaraion and assignment to a variable; see Function declaration statements for details.
Note that this will not work:
local factorial = function ( n ) if n <= 2 then return n else return n * factorial( n - 1 ) end end
Since the function declaration is processed before the local variable assignment statement is complete, "factorial" inside the function body refers to the (probably undefined) global variable of that name. This problem may be avoided by declaring the local variable first and then assigning it in a subsequent statement.
Statements
A statement is the basic unit of execution: one assignment, control structure, function call, variable delcaration, etc.
A chunk 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.
A block is also a sequence of statements, just like a chunk. A block can be delimited to create a single statement: do block end
. These may be used to limit the scope of local variables, or to add a return
or break
in the middle of another block.
Assignments
variable-list = expression-list
The variable-list is a comma-separated list of variables; the expression-list is a comma-separated list of one or more expressions. All expressions are evaluated before any assignments are performed, so a, b = b, a
will swap the values of a and b.
Local variable declarations
local variable-list
local variable-list = expression-list
Local variables may be declared anywhere within a block. 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 in Assignments above.
Note that visibility of the local variable begins with the statement after the local variable declaration. So a declaration like local 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.
Control structures
while exp do block end
The while statement repeats a block as long as an expression evaluates to a true value.
repeat block until exp
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.
for name = exp1, exp2, exp3 do block end
The first form of the for loop will declare a local variable, and repeat the block for values from exp1 to exp2 adding exp3 on each iteration. exp3 may be omitted, in which case 1 is used. All expressions are evaluated once before the loop is started.
This form of the for loop is roughly equivalent to
do local var, limit, step = tonumber( exp1 ), tonumber( exp2 ), tonumber( exp3 ) if not ( var and limit and step ) then error() end while ( step > 0 and var <= limit ) or ( step <= 0 and var >= limit ) do local name = var block var = var + step end end
except that the variables var, limit, and step are not accessible anywhere else. Note that the variable name is local to the block; to use the value after the loop, it must be copied to a variable declared outside the loop.
for var-list in exp-list do block end
The second form of the for loop works with iterator functions. As in the first form, the exp-list is evaluated only once before beginning the loop.
This form of the for loop is roughly equivalent to
do local func, static, var = exp-list while true do local var-list = func( static, var ) var = var1 -- var1 is the first variable in var-list if var == nil then break end block end end
except that again the variables func, static, and var are not accessible anywhere else. Note that the variables in var-list are local to the block; to use them after the loop, they must be copied to variables declared outside the loop.
Often the exp-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.
if exp1 then block1 elseif exp2 then block2 else block3 end
Executes block1 if exp1 returns true, otherwise executes block2 if exp2 returns true, and block3 otherwise. The else block3
portion may be omitted, and the elseif exp2 then block2
portion may be repeated or omitted as necessary.
return expression-list
The return statement is used to return values from a function or a chunk (which is just a function). The expression-list is a comma-separated list of zero or more expressions.
Lua implements tail calls: if expression-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 as getfenv()
and debug.traceback()
.
The return statement must be the last statement in its block. If for some reason a return is needed in the middle of a block, an explicit block do 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 its block. If for some reason a break is needed in the middle of a block, an explicit block do break end
may be used.
Function calls as statements
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.
Function declaration statements
Lua provides syntactic sugar to make declaring a function and assigning it to a variable more natural. The following pairs of declaraions are equivalent
-- Basic declaration function func( var-list ) block end func = function ( var-list ) block end
-- Local function local function func( var-list ) block end local func; func = function ( var-list ) block end
-- Function as a field in a table function table.func( var-list ) block end table.func = function ( var-list ) block end
-- Function as a method in a table function table:func( var-list ) block end table.func = function ( self, var-list ) block end
Note the colon notation here parallels the colon notation for function calls, adding an implicit argument named "self" at the beginning of the arguments list.
Error handling
Errors may be "thrown" using the error() and assert() functions. To "catch" errors, use pcall() or xpcall(). Note that certain internal Scribunto errors cannot be caught in Lua code.
Garbage collection
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 a garbage 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 via weak 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.
Standard libraries
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.
Basic functions
_G
This variable holds a reference to the current global variable table; the global variable foo
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 = 1 mw.log( foo ) -- logs "1" _G.foo = 2 mw.log( foo ) -- logs "2" _G = {} -- _G no longer points to the global variable table _G.foo = 3 mw.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 variables for k, v in pairs( _G ) do mw.log( k, v ) end
-- Log the creation of new global variables setmetatable( _G, { __newindex = function ( t, k, v ) mw.log( "Creation of new global variable '" .. k .. "'" ) rawset( t, k, v ) end } )
_VERSION
A string containing the running version of Lua, e.g. "Lua 5.1".
assert
assert( v, message, ... )
If v
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.
If v
is any other value, assert returns all arguments including v
and message
.
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 to assert
:
-- This doesn't check for errors local result1, result2, etc = func( ... ) -- This works the same, but does check for errors local result1, result2, etc = assert( func( ... ) )
error
error( message, level )
Issues an error, with text message
.
error
normally adds some information about the location of the error. If level
is 1 or omitted, that information is the location of the call to error
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
getfenv( f )
Note this function may not be available, depending on allowEnvFuncs
in the engine configuration.
Returns an environment (global variable table), as specified by f
:
- If 1, nil, or omitted, returns the environment of the function calling
getfenv
. Often this will be the same as _G. - Integers 2–10 return the environment of functions higher in the call stack. For example, 2 returns the environment for the function that called the current function, 3 returns the environment for the function calling that function, and so on. An error will be raised if the value is higher than the number of function calls in the stack, or if the targeted stack level returned with a tail call.
- Passing a function returns the environment that will be used when that function is called.
The environments used by all standard library functions and Scribunto library functions are protected. Attempting to access these environments using getfenv
will return nil instead.
getmetatable
getmetatable( table )
Returns the metatable of a table. Any other type will return nil.
If the metatable has a __metatable field, that value will be returned instead of the actual metatable.
ipairs
ipairs( t )
Returns three values: an iterator function, the table t
, and 0. This is intended for use in the iterator form of for
:
for i, v in ipairs( t ) do block end
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
next( table, key )
This allows for iterating over the keys in a table. If key
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 expression next( 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 a numerical for or ipairs.
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
pairs( t )
Returns three values: an iterator function (next or a work-alike), the table t
, and nil. This is intended for use in the iterator form of for
:
for k, v in pairs( t ) do block end
This will iterate over the key-value pairs in t
just as next would; see the documentation for next for restrictions on modifying the table during traversal.
The standard behavior may be overridden by providing a __pairs metamethod. If that metamethod exists, the call to pairs will return the three values returned by __pairs( t )
instead.
pcall
pcall( f, ... )
Calls the function f
with the given arguments in protected mode. This means that if an error is raised during the call to f
, pcall will return false and the error message raised. If no error occurs, pcall will return true and all values returned by the call.
In pseudocode, pcall
might be defined something like this:
function pcall( f, ... ) try return true, f( ... ) catch ( message ) return false, message end end
rawequal
rawequal( a, b )
This is equivalent to a == b
except that it ignores any __eq metamethod.
rawget
rawget( table, k )
This is equivalent to table[k]
except that it ignores any __index metamethod.
rawset
rawset( table, k, v )
This is equivalent to table[k] = v
except that it ignores any __newindex metamethod.
select
select( index, ... )
If index
is a number, returns all arguments in ...
after that index. If index
is the string '#', returns the count of arguments in ...
.
In other words, select
is something roughly like the following except that it will work correctly even when ...
contains nil values (see documentation for # and unpack for the problem with nils).
function select( index, ... ) local t = { ... } if index == '#' then return #t else return unpack( t, index ) end end
setmetatable
setmetatable( table, metatable )
Sets the metatable of a table. metatable
may be nil, but must be explicitly provided.
If the current metatable has a __metatable field, setmetatable
will throw an error.
tonumber
tonumber( value, base )
Tries to convert value
to a number. If it is already a number or a string convertible to a number, then tonumber
returns this number; otherwise, it returns nil.
The optional base
(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 in E notation, and may have a leading "0x" to indicate base 16. In other bases, only unsigned integers are accepted.
tostring
tostring( value )
Converts value
to a string. See Data types above for details on how each type is converted.
The standard behavior for tables may be overridden by providing a __tostring metamethod. If that metamethod exists, the call to tostring will return the single value returned by __tostring( value )
instead.
type
type( value )
Returns the type of value
as a string: "nil", "number", "string", "boolean", "table", or "function".
unpack
unpack( table, i, j )
Returns values from the given table, something like table[i], table[i+1], ···, table[j]
would do if written out manually. If nil or not given, i
defaults to 1 and j
defaults to #table
.
Note that results are not deterministic if table
is not a sequence and j
is nil or unspecified; see Length operator for details.
xpcall
xpcall( f, errhandler )
This is much like pcall
, except that the error message is passed to the function errhandler
before being returned.
In pseudocode, xpcall
might be defined something like this:
function xpcall( f, errhandler ) try return true, f() catch ( message ) message = errhandler( message ) return false, message end end
Debug library
debug.traceback
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 library
math.abs
math.abs( x )
Returns the absolute value of x
.
math.acos
math.acos( x )
Returns the arc cosine of x
(given in radians).
math.asin
math.asin( x )
Returns the arc sine of x
(given in radians).
math.atan
math.atan( x )
Returns the arc tangent of x
(given in radians).
math.atan2
math.atan2( y, x )
Returns the arc tangent of y/x
(given in radians), using the signs of both parameters to find the
quadrant of the result.
math.ceil
math.ceil( x )
Returns the smallest integer larger than or equal to x
.
math.cos
math.cos( x )
Returns the cosine of x
(given in radians).
math.cosh
math.cosh( x )
Returns the hyperbolic cosine of x
.
math.deg
math.deg( x )
Returns the angle x
(given in radians) in degrees.
math.exp
math.exp( x )
Returns the value .
math.floor
math.floor( x )
Returns the largest integer smaller than or equal to x
.
math.fmod
math.fmod( x, y )
Returns the remainder of the division of x
by y
that rounds the quotient towards zero.
math.frexp
math.frexp( x )
Returns two values m
and e
such that:
- If
x
is finite and non-zero: ,e
is an integer, and the absolute value ofm
is in the range - If
x
is zero:m
ande
are 0 - If
x
is NaN or infinite:m
isx
ande
is not specified
math.huge
The value representing positive infinity; larger than or equal to any other numerical value.
math.ldexp
math.ldexp( m, e )
Returns (e
should be an integer).
math.log
math.log( x )
Returns the natural logarithm of x
.
math.log10
math.log10( x )
Returns the base-10 logarithm of x
.
math.max
math.max( x, ... )
Returns the maximum value among its arguments.
Behavior with NaNs is not specified. With the current implementation, NaN will be returned if x
is NaN, but any other NaNs will be ignored.
math.min
math.min( x, ... )
Returns the minimum value among its arguments.
Behavior with NaNs is not specified. With the current implementation, NaN will be returned if x
is NaN, but any other NaNs will be ignored.
math.modf
math.modf( x )
Returns two numbers, the integral part of x
and the fractional part of x
.
math.pi
The value of .
math.pow
math.pow( x, y )
Equivalent to x^y
.
math.rad
math.rad( x )
Returns the angle x
(given in degrees) in radians.
math.random
math.random( m, n )
Returns a pseudo-random number.
The arguments m
and n
may be omitted, but if specified must be convertible to integers.
- With no arguments, returns a real number in the range
- With one argument, returns an integer in the range
- With two arguments, returns an integer in the range
math.randomseed
math.randomseed( x )
Sets x
as the seed for the pseudo-random generator.
Note that using the same seed will cause math.random
to output the same sequence of numbers.
math.sin
math.sin( x )
Returns the sine of x
(given in radians).
math.sinh
math.sinh( x )
Returns the hyperbolic sine of x
.
math.sqrt
math.sqrt( x )
Returns the square root of x
. Equivalent to x^0.5
.
math.tan
math.tan( x )
Returns the tangent of x
(given in radians).
math.tanh
math.tanh( x )
Returns the hyperbolic tangent of x
.
Operating system library
os.clock
os.clock()
Returns an approximation of the amount in seconds of CPU time used by the program.
os.date
os.date( format, time )
- Language library's formatDate may be used for more comprehensive date formatting
Returns a string or a table containing date and time, formatted according to format
. If the format is omitted or nil, "%c" is used.
If time
is given, it is the time to be formatted (see os.time()
). Otherwise the current time is used.
If
format
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:
- year (full)
- month (1–12)
- day (1–31)
- hour (0–23)
- min (0–59)
- sec (0–61)
- wday (weekday, Sunday is 1)
- yday (day of the year)
- isdst (daylight saving flag, a boolean; may be absent if the information is not available)
If format is not "*t", then date returns the date as a string, formatted according to the same rules as the C function strftime.
os.difftime
os.difftime( t2, t1 )
Returns the number of seconds from t1
to t2
.
os.time
os.time( table )
Returns a number representing the current 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".
Package library
require
require( modulename )
Loads the specified module.
First, it looks in package.loaded[modulename]
to see if the module is already loaded. If so, returns package.loaded[modulename]
.
Otherwise, it calles each loader in the package.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 into package.loaded[modulename]
and is returned.
See the documentation for package.loaders
for information on the loaders available.
package.loaded
This table holds the loaded modules. The keys are the module names, and the values are the values returned when the module was loaded.
package.loaders
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 by require. Otherwise, it must return nil.
Scribunto provides two searchers:
- Look in
package.preload[modulename]
for the loader function
- Look in the modules provided with Scribunto for the module name, and if that fails look in the Module: namespace. The "Module:" prefix must be provided.
Note that the standard Lua loaders are not included.
package.preload
This table holds loader functions, used by the first searcher Scribunto includes in package.loaders.
package.seeall
package.seeall( table )
Sets the __index metamethod for table
to _G.
String library
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 the Scribunto Ustring library.
string.byte
string.byte( s, i, j )
If the string is considered as an array of bytes, returns the byte values for s[i]
, s[i+1]
, ···, s[j]
.
The default value for i
is 1;
the default value for j
is i
.
string.char
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.
string.find
string.find( s, pattern, init, plain )
Looks for the first match of pattern
in the string s
. If it finds a match, then find
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 argument init
specifies where to start the search; its default value is 1 and can be negative. A value of true as a fourth, optional argument plain
turns off the pattern matching facilities, so the function does a plain "find substring" operation, with no characters in pattern
being considered "magic".
Note that if plain
is given, then init
must be given as well.
string.format
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 the printf
format specifiers:
- Recognized flags are '-', '+', ' ', '#', and '0'.
- Integer field widths up to 99 are supported. '*' is not supported.
- Integer precisions up to 99 are supported. '*' is not supported.
- Length modifiers are not supported.
- Recognized conversion specifiers are 'c', 'd', 'i', 'o', 'u', 'x', 'X', 'e', 'E', 'f', 'g', 'G', 's', '%', and the non-standard 'q'.
- Positional specifiers (e.g. "%2$s") are not supported.
The conversion specifier 'q' is like 's', 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 in Data types; other types are not automatically converted to strings. Strings containing NUL characters (byte value 0) are not properly handled.
string.gmatch
string.gmatch( s, pattern )
Returns an iterator function that, each time it is called, returns the next captures from pattern
over string s
. If pattern
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.
string.gsub
string.gsub( s, pattern, repl, n )
Returns a copy of s
in which all (or the first n
, if given) occurrences of the pattern
have been replaced by a replacement string specified by repl
, which can be a string, a table, or a function. gsub
also returns, as its second value, the total number of matches that occurred.
If repl
is a string, then its value is used for replacement. The character %
works as an escape character: any sequence in repl
of the form %n
,
with n between 1 and 9, stands for the value of the n-th captured substring. The sequence %0
stands for the whole match, and the sequence %%
stands for a single %
.
If repl
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.
If repl
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).
string.len
string.len( s )
Returns the length of the string, in bytes. Is not confused by ASCII NUL characters. Equivalent to #s
.
string.lower
string.lower( s )
Returns a copy of this string with all ASCII uppercase letters changed to lowercase. All other characters are left unchanged.
string.match
string.match( s, pattern, init )
Looks for the first match of pattern
in the string. If it finds one, then match
returns the captures from the pattern; otherwise it returns nil. If pattern
specifies no captures, then the whole match is returned.
A third, optional numerical argument init
specifies where to start the search; its default value is 1 and can be negative.
string.rep
string.rep( s, n )
Returns a string that is the concatenation of n
copies of the string s
.
string.reverse
string.reverse( s )
Returns a string that is the string s
reversed (bytewise).
string.sub
string.sub( s, i, j )
Returns the substring of s
that starts at i
and continues until j
; i
and j
can be negative. If j
is nil or omitted, -1 is used.
In particular, the call string.sub(s,1,j)
returns a prefix of s
with length j
, and string.sub(s, -i)
returns a suffix of s
with length i
.
string.upper
string.upper( s )
Returns a copy of this string with all ASCII lowercase letters changed to uppercase. All other characters are left unchanged.
Patterns
Character class
A character class is used to represent a set of characters. The following combinations are allowed in describing a character class:
- x: (where x is not one of the magic characters
^$()%.[]*+-?
) represents the character x 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.
%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
.
%x
: (where x is any non-alphanumeric character) represents the character x. 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 in set. A range of characters can be specified by separating the end characters of the range with a '-
'. All classes %x
described above can also be used as components in set. All other characters in set represent themselves. For example, [%w_]
(or [_%w]
) represents all alphanumeric characters plus the underscore, [0-7]
represents the octal digits, and [0-7%l%-]
represents the octal digits plus the lowercase letters plus the '-
' character.The interaction between ranges and classes is not defined. Therefore, patterns like [%a-z]
or [a-%%]
have no meaning.
[^set]
: represents the complement of set, where set is interpreted as above.
Pattern items
A pattern item can be
- a single character class, which matches any single character in the class;
- a single character class followed by '
*
', which matches 0 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;
- a single character class followed by '
+
', which matches 1 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;
- a single character class followed by '
-
', which also matches 0 or more repetitions of characters in the class. Unlike '*
', these repetition items will always match the shortest possible sequence;
- a single character class followed by '
?
', which matches 0 or 1 occurrence of a character in the class;
%n
, for n between 1 and 9; such item matches a substring equal to the n-th captured string (see below);
%bxy
, where x and y are two distinct characters; such item matches strings that start with x, end with y, and where the x and y are balanced. This means that, if one reads the string from left to right, counting +1 for an x and -1 for a y, the ending y is the first y where the count reaches 0. For instance, the item %b()
matches expressions with balanced parentheses.
Pattern
A pattern 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.
Captures
A pattern can contain sub-patterns enclosed in parentheses; they describe captures. 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 matching a*(.)%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.
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.
A pattern cannot contain embedded zero bytes (ASCII NUL). Use %z
instead.
Table library
Most functions in the table library assume that the table represents a sequence.
The functions table.foreach()
, table.foreachi()
, and table.getn()
may be available but are deprecated. Use a for loop with pairs(), a for loop with ipairs(), and the length operator instead.
table.concat
table.concat( table, sep, i, j )
Given an array where all elements are strings or numbers, returns table[i] .. sep .. table[i+1] ··· sep .. table[j]
.
The default value for sep
is the empty string, the default for i
is 1, and the default for j
is the length of the table. If i
is greater than j
, returns the empty string.
table.insert
table.insert( table, value )
table.insert( table, pos, value )
Inserts element value
at position pos
in table
, shifting up other elements to open space, if necessary. The default value for pos
is the length of the table plus 1, so that a call table.insert(t, x)
inserts x
at the end of table t
.
Elements up to #table
are shifted; see Length operator for caveats if the table is not a sequence.
table.maxn
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
function table.maxn( table )
local maxn, k = 0, nil
repeat
k = next( table, k )
if type( k ) == 'number' and k > maxn then
maxn = k
end
until not k
return maxn
end
table.remove
table.remove( table, pos )
Removes from table
the element at position pos
,
shifting down other elements to close the space, if necessary. Returns the value of the removed element. The default value for pos
is the length of the table, so that a call table.remove( t )
removes the last element of table t
.
Elements up to #table
are shifted; see Length operator for caveats if the table is not a sequence.
table.sort
table.sort( table, comp )
Sorts table elements in a given order, in-place, from table[1]
to table[#table]
. If comp
is given, then it must be a function that receives two table elements, and returns true when the first is less than the second (so that not comp(a[i+1],a[i])
will be true after the sort). If comp
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.
Scribunto libraries
All Scribunto libraries are located in the table mw
.
Base functions
mw.allToString
mw.allToString( ... )
Calls tostring() on all arguments, then concatenates them with tabs as separators.
mw.clearLogBuffer
mw.clearLogBuffer()
Removes all data logged with mw.log().
mw.clone
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.executeFunction
mw.executeFunction( func )
This creates a new copy of the frame object, calls the function with that as its parameter, then calls tostring() on all results and concatenates them (no separator) and returns the resulting string.
Note this will not work correctly from the debug console, as there is no frame object to copy.
mw.executeModule
mw.executeModule( func )
Executes the function in a sandboxed environment; the function cannot affect anything in the current environment, with the exception of side effects of calling any existing closures.
The name "executeModule" is because this is the function used when a module is loaded from the Module: namespace.
mw.getCurrentFrame
mw.getCurrentFrame()
Returns the current frame object.
mw.getLogBuffer
mw.getLogBuffer()
Returns the data logged by mw.log(), as a string.
mw.incrementExpensiveFunctionCount
mw.incrementExpensiveFunctionCount()
Adds one to the "expensive parser function" count, and throws an exception if it exceeds the limit (see $wgExpensiveParserFunctionLimit).
mw.log
mw.log( ... )
Passes the arguments to mw.allToString(), then appends the resulting string to the log buffer.
In the debug console, the function print()
is an alias for this function.
Frame object
The frame object is the interface to the parameters passed to {{#invoke:}}
, and to the parser.
frame.args
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}}
then frame.args[1]
will return "arg1", frame.args[2]
will return "arg2", and frame.args['name']
(or frame.args.name
) will return "arg3". It is also possible to iterate over arguments using pairs( frame.args )
or ipairs( frame.args )
.
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 keys 1 and 2.
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 is a metatable, not a real table of 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 the Table library.
If preprocessor syntax such as template invocations and triple-brace arguments are included within an argument to #invoke, they will be expanded before being passed to 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:getParent
frame:getParent()
Called on the frame created by {{#invoke:}}
, returns the frame for the page that called {{#invoke:}}
. Called on that frame, returns nil.
frame:expandTemplate
frame:expandTemplate{ title = title, args = table }
Note the use of named args syntactic sugar; see Function calls for details.
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 roughtly equivalent to wikitext like
-- {{template|{{! }}}}
frame:expandTemplate{ title = 'template', args = { '|' } }
-- This is roughtly equivalent to wikitext like
-- {{template|{{(( }}!{{)) }}}}
frame:expandTemplate{ title = 'template', args = { '{{!}}' } }
frame:preprocess
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. 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, use frame: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.
frame:getArgument
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
frame:newParserValue( text )
frame:newParserValue{ text = text }
Returns an object with one method, object:expand()
, that returns the result of frame:preprocess( text )
.
frame:newTemplateParserValue
frame:newTemplateParserValue{ title = title, args = table }
Returns an object with one method, object:expand()
, that returns the result of frame:expandTemplate
called with the given arguments.
frame:argumentPairs
frame:argumentPairs()
Same as pairs( frame.args )
. Included for backwards compatability.
Language library
Language codes are described at Language code.
Functions documented as mw.language.name
are available on the global mw.language
table; functions documented as mw.language:name
are methods of a language object (see mw.language.new
).
mw.language.fetchLanguageName
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 for inLanguage
.
mw.language.getContentLanguage
mw.language.getContentLanguage()
mw.getContentLanguage()
Returns a new language object for the wiki's default content language.
mw.language.isKnownLanguageTag
mw.language.isKnownLanguageTag( code )
Returns true if a language code is an IETF tag known to MediaWiki.
mw.language.isSupportedLanguage
mw.language.isSupportedLanguage( code )
Checks whether any localisation is available for that language tag in MediaWiki.
mw.language.isValidBuiltInCode
mw.language.isValidBuiltInCode( code )
Returns true 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.
mw.language.isValidCode
mw.language.isValidCode( code )
Returns true 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.
mw.language.new
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.
mw.language:getCode
lang:getCode()
Returns the language code for this language object.
mw.language:isRTL
lang:isRTL()
Returns true if the language is written right-to-left, false if it is written left-to-right.
mw.language:lc
lang:lc( s )
Converts the string to lowercase, honoring any special rules for the given language.
When the Ustring library is loaded, the mw.ustring.lower() function is implemented as a call to mw.language.getContentLanguage():lc( s )
.
mw.language:lcfirst
lang:lcfirst( s )
Converts the first character of the string to lowercase, as with lang:lc().
mw.language:uc
lang:uc( s )
Converts the string to uppercase, honoring any special rules for the given language.
When the Ustring library is loaded, the mw.ustring.upper() function is implemented as a call to mw.language.getContentLanguage():uc( s )
.
mw.language:ucfirst
lang:ucfirst( s )
Converts the first character of the string to uppercase, as with lang:uc().
mw.language:caseFold
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.
mw.language:formatNum
lang:formatNum( n )
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.
mw.language:formatDate
lang:formatDate( format, timestamp, local )
Formats a date according to the given format string. If timestamp
is omitted, the default is the current time. The valur for local
must be a boolean or nil; if true, the time is formatted in the server's local time rather than in UTC.
The format string and supported values for timestamp
are identical to those for the #time parser function from Extension:ParserFunctions. Note that backslashes may need to be doubled in the Lua string where they wouldn't in wikitext:
-- This outputs a newline, where n would output a literal "n"
lang:formatDate( '\n' )
-- This outputs a literal "n", where \5 would output a backslash
-- followed by the month number.
lang:formatDate( '\\n' )
-- This outputs a backslash followed by the month number, where \\5
-- would output two backslashes followed by the month number.
lang:formatDate( '\\\\n' )
mw.language:parseFormattedNumber
lang:parseFormattedNumber( s )
This takes a number as formatted by lang:formatNum() and returns the actual number. In other words, this is basically a language-aware version of tonumber()
.
mw.language:convertPlural
lang:convertPlural( n, ... )
lang:convertPlural( n, forms )
lang:plural( n, ... )
lang:plural( n, forms )
This chooses the appropriate grammatical form from forms
(which must be a sequence table) or ...
based on the number n
. For example, in English you might use n .. ' ' .. lang:plural( n, 'sock', 'socks' )
or n .. ' ' .. 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, see Help:Magic words#Language-dependent word conversions and translatewiki:FAQ#PLURAL for some details.
mw.language:convertGrammar
lang:convertGrammar( word, case )
lang:grammar( case, word )
- Note the different parameter order between the two aliases.
convertGrammar
matches the order of the method of the same name on MediaWiki's Language object, while grammar
matches the order of the parser function of the same name, documented at Help:Magic words#Localisation.
This chooses the appropriate inflected form of word
for the given inflection code case
.
The possible values for word
and case
are language-dependent, see Help:Magic words#Language-dependent word conversions and translatewiki:Grammar for some details.
mw.language:gender
lang:gender( what, masculine, feminine, neutral )
lang:gender( what, { masculine, feminine, neutral } )
Chooses the string corresponding to the gender of what
, which may be "male", "female", or a registered user name.
Site library
mw.site.currentVersion
A string holding the current version of MediaWiki.
mw.site.scriptPath
The value of $wgScriptPath.
mw.site.server
The value of $wgServer.
mw.site.siteName
The value of $wgSitename.
mw.site.stylePath
The value of $wgStylePath.
mw.site.namespaces
Table holding data for all namespaces, indexed by number.
The data available is:
- id: Namespace number.
- name: Local namespace name.
- canonicalName: Canonical namespace name.
- displayName: Set on namespace 0, the name to be used for display (since the name is often the empty string).
- hasSubpages: Whether subpages are enabled for the namespace.
- hasGenderDistinction: Whether the namespace has different aliases for different genders.
- isCapitalized: Whether the first letter of pages in the namespace is capitalized.
- isContent: Whether this is a content namespace.
- isIncludable: Whether pages in the namespace can be transcluded.
- isMovable: Whether pages in the namespace can be moved.
- isSubject: Whether this is a subject namespace.
- isTalk: Whether this is a talk namespace.
- defaultContentModel: The default content model for the namespace, as a string.
- aliases: List of aliases for the namespace.
- subject: Reference to the corresponding subject namespace's data.
- talk: Reference to the corresponding talk namespace's data.
- associated: Reference to the associated namespace's data.
A metatable is also set that allows for looking up namespaces by name (localized or canonical). For example, both mw.site.namespaces[4]
and mw.site.namespaces.Project
will return information about the Project namespace.
mw.site.contentNamespaces
Table holding just the content namespaces, indexed by number. See mw.site.namespaces for details.
mw.site.subjectNamespaces
Table holding just the subject namespaces, indexed by number. See mw.site.namespaces for details.
mw.site.talkNamespaces
Table holding just the talk namespaces, indexed by number. See mw.site.namespaces for details.
mw.site.stats
Table holding site statistics. Available statistics are:
- pages: Number of pages in the wiki.
- articles: Number of articles in the wiki.
- files: Number of files in the wiki.
- edits: Number of edits in the wiki.
- views: Number of views in the wiki. Not available if $wgDisableCounters is set.
- users: Number of users in the wiki.
- activeUsers: Number of active users in the wiki.
- admins: Number of users in group 'sysop' in the wiki.
mw.site.stats.pagesInCategory
mw.site.stats.pagesInCategory( category, which )
- This function is expensive
Gets statistics about the category. If which
is unspecified, nil, or "*", returns a table with the following properties:
- all: Total pages, files, and subcategories.
- subcats: Number of subcategories.
- files: Number of files.
- pages: Number of pages.
If which
is one of the above keys, just the corresponding value is returned instead.
Each new category queried will increment the expensive function count.
mw.site.stats.pagesInNamespace
mw.site.stats.pagesInNamespace( ns )
Returns the number of pages in the given namespace (specify by number).
mw.site.stats.usersInGroup
mw.site.stats.usersInGroup( group )
Returns the number of users in the given group.
Uri library
mw.uri.encode
mw.uri.encode( s, 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 reversable, as both spaces and underscores are encoded as '_'.
mw.uri.decode
mw.uri.decode( s, 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
mw.uri.anchorEncode( s )
Encodes a string for use in a MediaWiki URI fragment.
mw.uri.buildQueryString
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
mw.uri.parseQueryString( s )
Decodes a query string to a table. Keys in the string without values will have a value of false; keys repeated multiple times will have sequence tables as values; and others will have strings as values.
mw.uri.canonicalUrl
mw.uri.canonicalUrl( page, query )
Returns a URI object for the canonical url for a page, with optional query string/table.
mw.uri.fullUrl
mw.uri.fullUrl( page, query )
Returns a URI object for the full url for a page, with optional query string/table.
mw.uri.localUrl
mw.uri.localUrl( page, query )
Returns a URI object for the local url for a page, with optional query string/table.
mw.uri.new
mw.uri.new( s )
Constructs a new URI object for the passed string or table. See the description of URI objects for the possible fields for the table.
mw.uri.validate
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.
URI object
The URI object has the following fields, some or all of which may be nil:
- protocol: String protocol/scheme
- user: String user
- password: String password
- host: String host name
- port: Integer port
- path: String path
- query: A table, as from mw.uri.parseQueryString
- fragment: String fragment.
The following properties are also available:
- userInfo: String user and password
- hostPort: String host and port
- authority: String user, password, host, and port
- queryString: String version of the query table
- relativePath: String path, query string, and fragment
tostring()
will give the URI string.
Methods of the URI object are:
mw.uri:parse
uri:parse( s )
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.
mw.uri:clone
uri:clone()
Makes a copy of the URI object.
mw.uri:extend
uri:extend( parameters )
Merges the parameters table into the object's query table.
Ustring library
The ustring library is intended to be a direct reimplementation of the standard String 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.
mw.ustring.maxPatternLength
The maximum allowed lengh of a pattern, in bytes.
mw.ustring.maxStringLength
The maximum allowed lengh of a string, in bytes.
mw.ustring.byte
mw.ustring.byte( s, i, j )
Returns individual bytes; identical to string.byte().
mw.ustring.byteoffset
mw.ustring.byteoffset( s, l, i )
Returns individual the byte offset of a character in the string. The default for both l
and i
is 1. i
may be negative, in which case it counts from the end of the string.
The character at l
== 1 is the first character starting at or after byte i
; the character at l
== 0 is the first character starting at or before byte i
. Note this may be the same character. Greater or lesser values of l
are calculated relative to these.
mw.ustring.char
mw.ustring.char( ... )
Much like string.char(), except that the integers are Unicode codepoints rather than byte values.
mw.ustring.codepoint
mw.ustring.codepoint( s, i, j )
Much like string.byte(), except that the return values are codepoints and the offsets are characters rather than bytes.
mw.ustring.find
mw.ustring.find( s, pattern, init, plain )
Much like string.find(), except that the pattern is extended as described in Ustring patterns and the init
offset is in characters rather than bytes.
mw.ustring.format
mw.ustring.format( format, ... )
Identical to string.format(). Widths and precisions for strings are expressed in bytes, not codepoints.
mw.ustring.gcodepoint
mw.ustring.gcodepoint( s, i, j )
Returns three values for iterating over the codepoints in the string. i
defaults to 1, and j
to -1. This is intended for use in the iterator form of for
:
for codepoint in mw.ustring.gcodepoint( s ) do
block
end
mw.ustring.gmatch
mw.ustring.gmatch( s, pattern )
Much like string.gmatch(), except that the pattern is extended as described in Ustring patterns.
mw.ustring.gsub
mw.ustring.gsub( s, pattern, repl, n )
Much like string.gsub(), except that the pattern is extended as described in Ustring patterns.
mw.ustring.isutf8
mw.ustring.isutf8( s )
Returns true if the string is valid UTF-8, false if not.
mw.ustring.len
mw.ustring.len( s )
Returns the length of the string in codepoints, or nil if the string is not valid UTF-8.
mw.ustring.lower
mw.ustring.lower( s )
Much like string.lower(), except that all characters with lowercase to uppercase definitions in Unicode are converted.
If the Language library is also loaded, this will instead call lc() on the default language object.
mw.ustring.match
mw.ustring.match( s, pattern, init )
Much like string.match(), except that the pattern is extended as described in Ustring patterns and the init
offset is in characters rather than bytes.
mw.ustring.rep
mw.ustring.rep( s, n )
Identical to string.rep().
mw.ustring.sub
mw.ustring.sub( s, i, j )
Much like string.sub(), except that the offsets are characters rather than bytes.
mw.ustring.toNFC
mw.ustring.toNFC( s )
Converts the string to Normalization Form C. Returns nil if the string is not valid UTF-8.
mw.ustring.toNFD
mw.ustring.toNFD( s )
Converts the string to Normalization Form D. Returns nil if the string is not valid UTF-8.
mw.ustring.upper
mw.ustring.upper( s )
Much like string.upper(), except that all characters with uppercase to lowercase definitions in Unicode are converted.
If the Language library is also loaded, this will instead call uc() on the default language object.
Ustring patterns
Patterns in the ustring functions use the same syntax as the String library patterns. The major difference is that the character classes are redefined in terms of Unicode 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 "Decimal Number".
%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.
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.
Planned Scribunto libraries
These libraries are planned, or are in Gerrit pending review.
Message library
This library is awaiting review: Gerrit change 48482
This library is an interface to the localisation messages and the MediaWiki: namespace.
Functions documented as mw.message.name
are available on the global mw.message
table; functions documented as mw.message:name
are methods of a message object (see mw.message.new
).
mw.message.new
mw.message.new( key, ... )
Creates a new message object for the given message key
.
The message object has no properies, but has several methods documented below.
mw.message.newFallbackSequence
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 properies, but has several methods documented below.
mw.message.newRawMessage
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's params()
method.
The message object has no properies, but has several methods documented below.
mw.message.rawParam
mw.message.rawParam( value )
Wraps the value so that it will not be parsed as wikitext by msg:parse()
.
mw.message.numParam
mw.message.numParam( value )
Wraps the value so that it will automatically be formatted as by lang:formatNum()
. Note this does not depend on the Language library actually being available.
mw.message.getDefaultLanguage
mw.message.getDefaultLanguage()
If the Language library is available, returns a Language object for the default language. Otherwise, returns the language code as a string.
mw.message:params
msg:params( ... )
msg:params( params )
Add parameters to the message, which may be passed as individual arguments or as a sequence table. Parameters must be numbers, strings, or the special values returned by mw.message.numParam() or mw.message.rawParam().
Returns the msg
object, to allow for call chaining.
mw.message:rawParams
msg:rawParams( ... )
msg:rawParams( params )
Like :params(), but has the effect of passing all the parameters through mw.message.rawParam() first.
Returns the msg
object, to allow for call chaining.
mw.message:numParams
msg:numParams( ... )
msg:numParams( params )
Like :params(), but has the effect of passing all the parameters through mw.message.numParam() first.
Returns the msg
object, to allow for call chaining.
mw.message:inLanguage
msg:inLanguage( lang )
Specifies the language to use when processing the message. lang
may be a string or a table with a getCode()
method (i.e. a Language object).
The default language is the one returned by mw.message.getDefaultLanguage()
.
Returns the msg
object, to allow for call chaining.
mw.message:useDatabase
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 is true.
Returns the msg
object, to allow for call chaining.
mw.message:title
msg:title( title )
Specifies the title to use when processing the message; this affects magic words like {{PAGENAME}}
and {{NAMESPACE}}
. The value may be nil (to use the default), a string, or a table with a prefixedText
field (i.e. a Title object).
The default is the title of the page being parsed.
Returns the msg
object, to allow for call chaining.
mw.message:parse
msg:parse()
- This function is expensive
Parses the message to HTML, and returns that text as a string.
Note this is not likely to be extremely useful, as {{#invoke:}}
must return wikitext.
mw.message:parseAsBlock
msg:parseAsBlock()
- This function is expensive
Parses the message to HTML, and returns that text as a string. The result is always enclodes in a block-level tag.
Note this is not likely to be extremely useful, as {{#invoke:}}
must return wikitext.
mw.message:plain
msg:plain()
Substitutes the parameters and returns the message wikitext as-is. Template calls and parser functions are intact.
mw.message:text
msg:text()
Processes parameters, templates transclusions, parser functions, and such, and returns the resulting wikitext.
mw.message:escaped
msg:escaped()
Processes parameters, templates transclusions, parser functions, and such. Except within raw parameters, any <
, >
, "
, '
, and &
are replaced by the corresponding HTML entities.
mw.message:exists
msg:exists()
Returns a boolean indicating whether the message key exists.
mw.message:isBlank
msg:isBlank()
Returns a boolean indicating whether the message key has content. Returns true if the message key does not exist or the message is the empty string.
mw.message:isDisabled
msg:isDisabled()
Returns a boolean indicating whether the message key is disabled. Returns true if the message key does not exists or if the message is the empty string or the string "-".
Title library
This library is awaiting review: Gerrit change 47913
mw.title.equals
mw.title.equals( a, b )
Test for whether two titles are equal. Note that fragments are ignored in the comparison.
mw.title.compare
mw.title.compare( a, b )
Returns -1, 0, or 1 to indicate whether the title a
is less than, equal to, or greater than title b
mw.title.getCurrentTitle
mw.title.getCurrentTitle()
Returns the title object for the current page.
mw.title.new
mw.title.new( text, namespace )
mw.title.new( id )
- This function is expensive
Creates a new title object. The expensive function count will be incremented if the title object created is not for the current page and is not for a title that has already been loaded.
If a number id
is given, an object is created for the title with that page_id. If the page_id does not exist, returns nil.
If a string text
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 in mw.site.namespaces
) will be used. If the text is not a valid title, nil is returned.
mw.title.makeTitle
mw.title.makeTitle( namespace, title, fragment, interwiki )
- This function is expensive
Creates a title object with title title
in namespace namespace
, optionally with the specified fragment
and interwiki
prefix. namespace
may be any key found in mw.site.namespaces
. If the resulting title is not valid, returns nil. This function is expensive under the same conditions as mw.title.new()
.
Note that mw.title.new( 'Module:Foo', 'Template' )
will create an object for the page Module:Foo, while mw.title.makeTitle( 'Template', 'Module:Foo' )
will create an object for the page Template:Module:Foo.
Title objects
A title object has a number of properties and methods. Most of the properties are read-only.
- id: The page_id. 0 if the page does not exist.
- interwiki: The interwiki prefix, or the empty string if none.
- namespace: The namespace number.
- fragment: The fragment, or the empty string. May be assigned.
- nsText: The text of the namespace for the page.
- subjectNsText: The text of the subject namespace for the page.
- text: The title of the page, without the namespace or interwiki prefixes.
- prefixedText: The title of the page, with the namespace and interwiki prefixes.
- fullText: The title of the page, with the namespace and interwiki prefixes and the fragment.
- rootText: If this is a subpage, the title of the root page without prefixes. Otherwise, the same as
title.text
.
- baseText: If this is a subpage, the title of the page it is a subpage of without prefixes. Otherwise, the same as
title.text
.
- subpageText: If this is a subpage, just the subpage name. Otherwise, the same as
title.text
.
- canTalk: Whether the page for this title could have a talk page.
- exists: Whether the page exists.
- isContentPage: Whether this title is in a content namespace.
- isExternal: Whether this title has an interwiki prefix.
- isLocal: Whether this title is in this project. For example, on the English Wikipedia, any other Wikipedia is considered "local" while Wiktionary and such are not.
- isRedirect: Whether this is the title for a page that is a redirect.
- isSpecialPage: Whether this is the title for a possible special page (i.e. a page in the Special: namespace).
- isSubpage: Whether this title is a subpage of some other title.
- isTalkPage: Whether this is a title for a talk page.
- isSubpageOf( title2 ): Whether this title is a subpage of the given title.
- inNamespace( ns ): Whether this title is in the given namespace. Namespaces may be specified by anything that is a key found in
mw.site.namespaces
.
- inNamespaces( ... ): Whether this title is in any of the given namespaces. Namespaces may be specified by anything that is a key found in
mw.site.namespaces
.
- hasSubjectNamespace( ns ): Whether this title's subject namespace is in the given namespace. Namespaces may be specified by anything that is a key found in
mw.site.namespaces
.
- contentModel: The content model for this title, as a string.
- basePageTitle: The same as
mw.title.makeTitle( title.namespace, title.baseText )
.
- rootPageTitle: The same as
mw.title.makeTitle( title.namespace, title.rootText )
.
- talkPageTitle: The same as
mw.title.makeTitle( mw.site.namespaces[title.namespace].talk.id, title.text )
, or nil if this title cannot have a talk page.
- subjectPageTitle: The same as
mw.title.makeTitle( mw.site.namespaces[title.namespace].subject.id, title.text )
.
- subPageTitle( text ): The same as
mw.title.makeTitle( title.namespace, title.text .. '/' .. text )
.
- partialUrl(): Returns
title.text
encoded as it would be in a URL.
- fullUrl( query, proto ): Returns the full URL (with optional query table/string) for this title.
proto
may be specified to control the scheme of the resulting url: "http", "https", "relative" (the default), or "canonical".
- localUrl( query ): Returns the local URL (with optional query table/string) for this title.
- canonicalUrl( query ): Returns the canonical URL (with optional query table/string) for this title.
Title objects may be compared using Relational operators. tostring( title )
will return title.prefixedText
.
Differences from standard Lua
The following functions have been modified:
- setfenv()
- getfenv()
- May not be available, depending on the configuration. If available, attempts to access parent environments will fail.
- getmetatable()
- Works on tables only to prevent unauthorized access to parent environments.
- tostring()
- Pointer addresses of tables and functions are not provided. This is to make memory corruption vulnerabilities more difficult to exploit.
- pcall()
- xpcall()
- Certain internal errors cannot be intercepted.
- require()
- Can fetch certain built-in modules distributed with Scribunto, as well as modules present in the Module namespace of the wiki. To fetch wiki modules, use the full page name including the namespace. Cannot otherwise access the local filesystem.
The following packages are mostly removed. Only those functions listed are available:
- package.*
- Filesystem and C library access has been removed. Available functions and tables are:
- package.loaded
- package.preload
- package.loaders
- Loaders which access the local filesystem or load C libraries are not present. A loader for Module-namespace pages is added.
- package.seeall()
- os.*
- There are some insecure functions in here, such as os.execute(), which can't be allowed. Available functions are:
- debug.*
- Most of the functions are insecure. Available functions are:
The following functions and packages are not available:
- collectgarbage()
- module()
- coroutine.*
- No application is known for us, so it has not been reviewed for security.
- dofile()
- loadfile()
- io.*, file.*
- Allows local filesystem access, which is insecure.
- load()
- loadstring()
- These were omitted to allow for static analysis of the Lua source code. Also, allowing these would allow Lua code to be added directly to article and template pages, which was not desired for usability reasons.
- print()
- This was discussed on wikitech-l and it was decided that it should be omitted in favour of return values, to improve code quality. If necessary, mw.log() may be used to output information to the debug console.
- string.dump()
- May expose private data from parent environments.
Writing Scribunto libraries
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:
- The PHP portion of the library.
- The Lua portion of the library.
- The PHP portion of the test cases.
- The Lua portion of the test cases.
- The documentation.
Existing libraries serve as a good example.
Library
The PHP portion of the library is a class that must extend Scribunto_LuaLibraryBase
. See the documentation for that class for implementation details. In the Scribunto extension, this file should be placed in engines/LuaCommon/NameLibrary.php
, and a mapping added to Scribunto_LuaEngine::$libraryClasses
. Other extensions should use the ScribuntoExternalLibraries
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 in engines/LuaCommon/lualib/mw.name.lua
. This file should generally include boilerplate something like this:
local object = {}
local php
function object.setupInterface( options )
-- Remove setup function
object.setupInterface = nil
-- Copy the PHP callbacks to a local variable, and remove the global
php = mw_interface
mw_interface = nil
-- Do any other setup here
-- Install into the mw global
mw = mw or {}
mw.ext = mw.ext or {}
mw.ext.name = object
-- Indicate that we're loaded
package.loaded['mw.ext.name'] = object
end
return object
The module in engines/LuaCommon/lualib/libraryUtil.lua
(load this with local 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.
Test cases
The Scribunto extension includes a base class for test cases, Scribunto_LuaEngineTestBase
, which will run the tests against both the LuaSandbox and LuaStandalone engines. The library's test case should extend this class, and should not override static function suite()
. In the Scribunto extension, the test case should be in tests/engines/LuaCommon/NameLibraryTest.php
and added to the array in ScribuntoHooks::unitTestsList()
(in common/Hooks.php
); extensions should add the test case in their own UnitTestsList
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 ClassNameTest extends Scribunto_LuaEngineTestBase {
protected static $moduleName = 'ClassNameTest';
function getTestModules() {
return parent::getTestModules() + array(
'ClassNameTest' => __DIR__ . 'ClassNameTests.lua';
);
}
}
This will load the file ClassNameTests.lua
as if it were the page "Module:ClassNameTests", expecting it to return an object with the following properties:
- count: Integer, number of tests
- provide( n ): Function that returns three values:
n
, the name of test n
, and a string that is the expected output for test n
.
- run( n ): Function that runs test
n
and returns one string.
If getTestModules()
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:
local testframework = require 'Module:TestFramework'
return testframework.getTestProvider( {
-- Tests go here
} )
Each test is itself a table, with the following properties:
- name: The name of the test.
- func: The function to execute.
- args: Optional table of arguments to pass to the function.
- expect: Results to expect.
- type: Optional "type" of the test, default is "Normal".
The type controls the format of expect
and how func
is called. Included types are:
- Normal:
expect
is a table of return values, or a string if the test should raise an error. func
is simply called.
- Iterator:
expect
is a table of tables of return values. func
is called as with a iterated for loop, and each iteration's return values are accumulated.
- ToString: Like "Normal", except each return value is passed through
tostring()
.
Documentation
Modules included in Scribunto should include documentation in the Scribunto libraries section above. Extension libraries should include documentation in a subpage of their own Extension page, and link to that documentation from somewhere appropriate.