Расширение:Scribunto/Справочник Lua
Это руководство по Lua в том виде, в каком он используется в MediaWiki с расширением Scribunto . Некоторые части производны от Lua 5.1 reference manual, доступного под лицензией MIT.
![]() | Здесь документирована последняя версия расширения Scribunto. Некоторые особенности могли ещё не дойти до всех проектов. |
Введение
Первые шаги
В вики-проекте с MediaWiki и подключенным Scribunto создайте страницу с заголовком, начинающимся с Module:
, например, Module:Bananas.
На эту новую страницу скопируйте следующий текст:
local p = {} --p означает package (пакет)
function p.hello( frame )
return "Hello, world!"
end
return p
Сохраните её, а затем на другой странице (не в модуле) напишите:
{{#invoke:Bananas|hello}}
При этом имя «Bananas» следует заменить на имя модуля, который вы только что создали. Этот код вызовет функцию «hello» из вашего модуля. При сохранении страницы и последующем просмотре фрагмент {{#invoke:Bananas|hello}}
будет заменён на текст, возвращаемый функцией, в данном случае — «Hello, world!»
Обычно лучше вызывать код на Lua посредством шаблона. При таком вызове с точки зрения вызывающей страницы нет разницы, написан ли шаблон с использованием Lua или на чистом вики-тексте. Использование шаблона также позволяет не вводить в основное пространство вики дополнительный усложнённый синтаксис.
Структура модуля
Сам по себе модуль должен возвращать Lua-таблицу, содержащую функции, которые можно вызвать через {{#invoke:}}
.
Обычно объявляют локальную переменную (как показано выше: локальная переменная — «p»), в которую помещается таблица, к этой таблице добавляют функции, и в конце кода модуля эту таблицу возвращают.
Все функции, не добавленные к этой таблице, глобальные они или локальные, через {{#invoke:}}
доступны не будут; однако глобальные могут быть доступны из других модулей, загруженных с помощью require()
.
Обычно хорошим стилем для модулей считается объявлять все функции и переменные локальными.
Доступ к параметрам из вики-текста
Функциям, вызываемым с помощью {{#invoke:}}
, передаётся единственный параметр, а именно объект frame. Для доступа к параметрам, переданным через {{#invoke:}}
, в коде обычно используется args
. Та же таблица может быть использована для доступа к параметрам, переданным в шаблон, содержащий {{#invoke:}}
. Для этого необходимо предварительно вызвать метод frame:getParent()
и получить доступ к args
возвращённого этим методом фрейма.
Также объект frame используется для доступа к специфичным для конкретного контекста возможностям парсера вики-текста, например, к вызову функций парсера, вызову шаблонов или обработке произвольных строк вики-текста.
Возвращаемый текст
Обычно функция модуля возвращает одну символьную строку (строковый литерал); все возвращаемые значения пропускаются через tostring(), а затем конкатенируются (сшиваются) без разделителей. Именно эта строка и встраивается в вики-текст в качестве результата вызова {{#invoke:}}
.
В тот момент разбора страницы, когда обрабатывается вызов модуля, шаблоны уже развёрнуты, функции парсера и теги расширений уже обработаны, а предварительные преобразования (например, подстановка подписи вместо тильд или конвейерный приём [pipe trick]) уже совершены. Поэтому модули не могут использовать эти возможности в выходном тексте. Например, если модуль возвращает "Hello, [[world]]! {{welcome}}"
, то на странице это будет выглядеть как «Hello, world! {{welcome}}».
Также следует помнить, что подстановки вида subst выполняются на более ранней стадии обработки, поэтому код {{subst:#invoke:}}
выполнится не при первом сохранении. Другие подстановки сработают, а эта останется «висеть» в вики-тексте и выполнится только при следующей правке. Поэтому такой подстановки следует избегать.
Документирование модуля
Scribunto позволяет документировать модули, автоматически связывая модуль с вики-текстовой страницей документации; по умолчанию для этого используется подстраница модуля с именем «/doc», содержимое которой внедряется над исходным кодом страницы модуля. Например, документация для модуля «Module:Bananas» может быть размещена на странице «Module:Bananas/doc».
Документирование модуля может быть настроено с помощью следующих системных сообщений в пространстве имён MediaWiki:
scribunto-doc-page-name
—Устанавливает имя страницы, используемой для документирования. Имя модуля (без префикса Module:) передается как$1
. Если в пространстве имен модуля, указанные здесь страницы будут интерпретироваться как викитекст, а не как исходный код Lua, и их нельзя использовать с{{#invoke:}}
. По умолчанию это "Module:$1/doc", т.е. подстраница модуля /doc. Обратите внимание, что в этом сообщении нельзя использовать функции синтаксического анализатора и другое раскрытие фигурных скобок.scribunto-doc-page-does-not-exist
— Сообщение отображается, когда страница документа не существует. Имя страницы передается как$1
. По умолчанию пусто.scribunto-doc-page-show
— Сообщение отображается, когда страница документа существует. Имя страницы передается как$1
. По умолчанию включена страница документации.scribunto-doc-page-header
— Заголовок отображается при просмотре самой страницы документации. Имя модуля (без префикса Module:) передается как$1
. По умолчанию краткое объяснение просто отображается курсивом.
Обратите внимание на то, что на страницы модулей нельзя напрямую добавлять категории или интервики-ссылки.
Их можно разместить на странице документации внутри тегов <includeonly>...</includeonly>
, где они будут применены к модулю при включении страницы документации на страницу модуля.
Язык Lua
Токены
Имена в Lua (также называемые идентификаторами) могут быть любыми текстовыми строками, состоящими из латинских букв, цифр и знаков подчёркивания, но не начинающимися с цифры. Имена регистрозависимы, т. е. «foo», «Foo», и «FOO», это разные имена.
Нижеследующие ключевые слова зарезервированы и не могут быть использованы в качестве имён:
and
break
do
else
elseif
end
false
for
function
if
in
local
nil
not
or
repeat
return
then
true
until
while
Имена, начинающиеся с символа подчёркивания, за которым следуют заглавные буквы, зарезервированы для внутренних глобальных переменных Lua.
Другие токены:
#
%
(
)
*
+
,
-
--
.
..
...
/
:
;
<
<=
=
==
>
>=
[
]
^
{
}
~=
Комментарии
Комментарий начинается с символов --
в любом месте кода, кроме символьных строк. Если после --
сразу же идёт открывающая широкая скобка, то комментарий будет продолжаться до соответствующей закрывающей широкой скобки; в противном случае комментарий продолжается до конца строки.
-- Комментарий в Lua начинается с двойного дефиса и продолжается до конца строки.
--[[ Многострочные символьные строки (строковые литералы) и комментарии
оформляются двойными квадратными скобками. ]]
--[=[ Комментарии, оформленные так, могут иметь другие вложенные --[[комментарии]]. ]=]
--[==[ Комментарии, похожие на этот, могут иметь другие
--[===[ пространные --[=[комментарии,]=] --вложенные
]===] многократно, даже если все они
--[[ неправильно оформлены широкими скобками! ]===]
]==]
Типы данных
Lua — динамически типизированный язык, что означает, что тип имеют не переменные и параметры функции, а только назначенные им значения. Все значения имеют тип.
В Lua есть восемь основных типов данных, однако только шесть из них задействованы в расширении Scribunto. Узнать тип значения можно с помощью функции type()
.
Функция tostring()
конвертирует значение в символьную строку. Функция tonumber()
может преобразовать значение в число, если это возможно. Если нет — вернёт nil. Других функций, существующих только для преобразования типа данных, в Lua нет.
Числа автоматически преобразуются в символьные строки, когда используются в ситуации, в которой ожидается вывод именно строкового литерала, например, при использовании в операции конкатенации. Соответственно, строковый литерал, если он в принципе распознаётся функцией tonumber()
, автоматически конвертируется в число при использовании арифметических операций. Если же ожидается вывод логического значения, то получение любого другого, кроме nil или false, интерпретируется как true.
nil
Значение «nil» имеет тип данных nil
и существует для представления отсутствия какого-либо значения.
Nil не может использоваться в качестве ключа в таблице, и нет никакой разницы между неназначенным ключом таблицы и ключом, назначенным значением nil.
При преобразовании nil в строковый литерал будет получена строка "nil". При преобразовании nil в логическое значение будет получено false.
boolean
Логических (булевых) значений два: true
и false
.
При преобразовании их в символьные строки будут получены строки "true" и "false".
В отличие от многих других языков, логические значения не могут быть напрямую преобразованы в числа. Также в Lua только false и nil в логических операциях считаются значением false; число 0 или пустая символьная строка считаются значением true.
string
Строки Lua считаются последовательностью 8-битных байтов; интерпретация их в соответствии с какой-либо конкретной кодировкой — задача приложения, использующего Lua.
Строковые литералы ограничиваются одинарными или двойными кавычками ('
или "
). Так же, как в JavaScript, но не как в PHP, между одинарными и двойными кавычками нет разницы. Определены следующие управляющие последовательности (escape-последовательности):
\a
(bell, звуковой сигнал, байт 7)\b
(backspace, возврат на 1 позицию, байт 8)\t
(horizontal tab, горизонтальная табуляция, байт 9)\n
(newline, перевод строки, байт 10)\v
(vertical tab, вертикальная табуляция, байт 11)\f
(form feed, прогон страницы (FF), байт 12)\r
(carriage return, возврат каретки, байт 13)\"
(double quote, двойные кавычки, байт 34)\'
(single quote, одинарные кавычки, байт 39)\\
(backslash, обратная косая черта, байт 92)
Непосредственно перенос строки также может быть включён в символьную строку, если экранировать его обратной косой чертой. Также можно включать в строки байты посредством управляющих последовательностей вида '\ddd', где ddd — это десятичное значение байта в диапазоне 0—255. Чтобы включить символы Unicode с использованием управляющих последовательностей, необходимо указать отдельные байты кодировки UTF-8 (от одного до четырёх); поэтому обычно проще вводить символы Unicode напрямую.
Строковые литералы могут быть обозначены с использованием широких скобок.
Открывающая широкая скобка состоит из двух подряд открывающих квадратных скобок, между которыми может располагаться произвольное количество знаков равенства, например, [[
, [=[
или [=====[
.
Открывающей широкой скобке должна соответствовать закрывающая широкая скобка, например, ]]
, ]=]
или ]=====]
.
В качестве особого случая: если после открывающей широкой скобки сразу же следует перенос строки, он не включается в символьную строку, но если перенос строки стоит непосредственно перед закрывающей широкой скобкой, то он в символьную строку входит.
В символьных строках, ограниченных широкими скобками, управляющие последовательности не интерпретируются.
-- Эта символьная строка, ограниченная широкими скобками
foo = [[
bar\tbaz
]]
-- эквивалентна этой, ограниченной кавычками
foo = 'bar\\tbaz\n'
Следует помнить, что все строки считаются истинными (true) при преобразовании к логическому типу данных (boolean). Это не похоже на ряд других языков программирования, в которых пустая строка считается ложной (false).
number
Lua имеет только один числовой тип, который обычно представляется как 64-битное значение двойной точности с плавающей запятой. В этом формате целые числа между -9007199254740992
(-2^53
) и 9007199254740992
(2^53
) могут быть представлены точно, в то время как бо́льшие числа и числа с дробной частью могут пострадать от ошибок округления.
В числовых константах в качестве десятичного разделителя используется точка (.
), а разделители групп разрядов не используются, например, 123456.78
. Также числа могут быть представлены с использованием экспоненциальной записи без пробелов, например, 1.23e-10
, 123.45e20
, или 1.23E+5
. Целые числа могут быть представлены в шестнадцатеричном виде с использованием префикса 0x
, например, 0x3A
.
Хотя и NaN, и бесконечности обоих знаков правильно хранятся и обрабатываются в Lua, под них не предоставлено соответствующих литералов. Константа math.huge
хранит положительную бесконечность, и её также можно получить, выполнив деление 1/0
. А с помощью деления 0/0
можно быстро сгенерировать NaN.
Следует помнить, что при преобразовании к логическому типу данных все числа (включая 0, NaN и бесконечности) дают true. Это не похоже на ряд других языков программирования, где число 0 даёт false. При конвертации в символьную строку все конечные числа переводятся в десятичную форму, если необходимо — в экспоненциальной форме; NaN даёт "nan"
или "-nan"
; бесконечности — "inf"
или "-inf"
.
table
Таблицы Lua — это ассоциативные массивы, похожие на массивы PHP или объекты JavaScript.
Таблицы создаются с использованием фигурных скобок. Пустая таблица: {}
. Чтобы заполнить поля таблицы при создании, в фигурные скобки можно включить список спецификаторов полей, разделённых запятыми и/или точками с запятой. Они принимают любую из нескольких форм:
[выражение1] = выражение2
здесь (первое) значение выражения1 используется как ключ, а (первое) значение выражения2 является значением.имя = выражение
, что эквивалентно["имя"] = выражение
выражение
, что примерно эквивалентно[i] = выражение
, где i является целым числом, а счёт начинается с 1 и увеличивается на 1 для каждого следующего спецификатора поля. Если последнему спецификатору будет соответствовать выражение, имеющее несколько значений, то будут использованы все они; в противном случае сохраняется только первое значение выражения.
Обращаться к полям таблицы можно с использованием формы записи с квадратными скобками, например, table[key]
. Символьные ключи, если они соответствуют требованиям к именам, позволяют использовать запись с точкой, например, table.key
, что эквивалентно записи table['key']
. Если значением поля таблицы является функция, её вызов может быть осуществлён в форме записи с двоеточием; например, table:func( ... )
, что соответствует table['func']( table, ... )
или table.func( table, ... )
.
Последовательностью называют таблицу с не-nil значениями, ключами для которых служат целые положительные числа от 1 до N (т. е. натуральные числа — прим. пер.), а для ключей, бо́льших N, значения не определены (nil). Множество функций Lua работают только с последовательностями и игнорируют ключи не натурального ряда.
В отличие от многих других языков, таких как PHP или JavaScript, как ключ может использоваться любое значение, кроме nil и NaN, и преобразование типов при этом не выполняется. Всё, представленное ниже, валидно и различается между собой:
-- Создание таблицы
t = {}
t["foo"] = "foo"
t.bar = "bar"
t[1] = "один"
t[2] = "два"
t[3] = "три"
t[12] = "номер двенадцать"
t["12"] = "строка двенадцать"
t[true] = "true"
t[tonumber] = "да, даже функции могут быть ключами таблицы"
t[t] = "yes, a table may be a table key too. Even in itself."
-- Теперь создаём таблицу, в целом эквивалентную верхней
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."
Аналогично, любое значение, кроме nil, может быть сохранено как значение таблицы. Хранение nil эквивалентно удалению ключа из таблицы, и обращение к несуществующему ключу даст значение nil.
Следует помнить, что в Lua неявного копирования таблиц не происходит; если таблица передаётся в качестве аргумента функции, которая затем изменяет ключи или значения таблицы, то эти изменения будут видны в вызывающем коде.
При преобразовании таблицы к символьной строке получим результат "table", но это может быть переопределено с помощью метаметода __tostring
. При логическом преобразовании даже пустая таблица даёт true.
function
Функции в Lua являются значениями первого класса: они могут создаваться анонимно, передаваться как аргументы, назначаться переменным и т. д.
Функции создаются с помощью ключевого слова function
и вызываются с помощью круглых скобок. Синтаксический сахар доступен для именованных функций, локальных функций и функций, которые являются значениями в таблице. Подробнее это изложено ниже в разделах Объявление функций и Вызов функций.
Функции в Lua являются замыканием, что означает, что они поддерживают ссылку на область, в которой они объявлены, и могут обращаться к переменным в этой области и управлять ими.
Подобно таблицам, если функция присвоена другой переменной или передана другой функции как аргумент, при её вызове всё равно будет вызван один и тот же внутренний «объект функции».
При преобразовании в строку результатом является "function".
Неподдерживаемые типы
Тип userdata используется для хранения непрозрачных значений, используемых в расширениях для Lua, написанных на других языках. Например, объект userdata может использоваться для хранения указателя или структуры языка Си. Чтобы Scribunto можно было использовать в окружениях, где компилированный пользователем код не допускается, в Scribunto нет расширений, создающих объекты userdata.
Тип thread представляет дескрипторы для сопрограмм, которые недоступны в песочнице Scribunto.
Метатаблицы
У каждой таблицы может быть ассоциированная таблица, известная как метатаблица (metatable). Поля метатаблицы используются некоторыми операциями и функциями для указания другого или резервного поведения таблицы. Метатаблица таблицы может быть получена вызовом функции getmetatable() и назначена функцией setmetatable().
Когда Lua обращается к полям метатаблицы с целью осуществления их мета-задач, это обращение по принципам подобно работе функции rawget().
Следующие поля метатаблицы влияют на саму таблицу:
- __index
- Это поле используется, когда чтение таблицы вида
табл[ключ]
вернуло бы nil. Если значение этого поля — таблица, доступ будет перенаправлен на эту таблицу, то есть__index[ключ]
(что может затем обращаться к __index уже той таблицы). Если значение этого поля — функция, она будет вызвана как__index( табл, ключ )
. При использовании функции rawget() обращения к этому метаметоду не происходит. - __newindex
- Это поле используется при записи в таблицу вида
табл[ключ] = значение
в случаях, когда вызовrawget( t, key )
вернул бы nil. Если значение этого поля — таблица, запись будет перенаправлена на неё, то есть__newindex[ключ] = значение
(что может затем обратиться к __newindex уже той таблицы). Если значение этого поля — функция, она будет вызвана как__newindex( табл, ключ, значение )
. При использовании функции rawset() обращения к этому метаметоду не происходит. - __call
- Это поле используется при попытке вызвать таблицу, то есть
табл( ··· )
. Значение должно быть функцией, которая вызывается как__call( табл, ··· )
. - __mode
- Это поле используется для создания таблиц со слабыми ссылками. Значение должно быть строкой. По умолчанию, любое значение, используемое как ключ или значение в какой-либо таблице, не будет удалено сборщиком мусора. Но если это метаполе содержит символ 'k', ключи в таблице могут быть удалены сборщиком мусора, если на них нет сильных ссылок. Если в метаполе есть символ 'v', по таким же принципам могут быть удалены значения в таблице. В обоих случаях при удалении ключа и/или значения пара ключ-значение из таблицы удаляется. Обратите внимание, что поведение программы не определено, если это поле будет изменено после назначения содержащей его таблицы как метатаблицы.
Другие поля метатаблиц включают:
Обратите внимание: в Lua у всех строк общая метатаблица, в которой __index
ссылается на таблицу string
. В Scribunto не доступны ни эта метатаблица, ни таблица string
, к которой она обращается; таблица string, доступная модулям, является копией.
Переменные
Переменные — это области памяти, хранящие значения. В Lua три вида переменных: глобальные переменные, локальные переменные и поля таблиц.
Имя представляет глобальную или локальную переменную (или аргумент функции, вид локальной переменной). Переменные считаются глобальными, если не были явно объявлены как локальные ключевым словом local
. Любая переменная, которой не присвоено значение, считается имеющей значение nil.
Глобальные переменные хранятся в таблице Lua, называемой окружением (environment). Эта таблица доступна как глобальная переменная _G
. Таблице глобальных переменных можно задать метатаблицу; метаметоды __index и __newindex будут использоваться при чтении и присвоении глобальных переменных, как в случае с полями любой другой таблицы.
Окружение функции может быть получено вызовом функции getfenv() и задано функцией setfenv(); в Scribunto эти функции или очень ограничены, или вообще недоступны.
Локальные переменные ограничены областью видимости; для подробностей см. Объявление локальных переменных.
Выражения
Выражение (expression) — что-то, у чего есть значение: литерал (строковый, числовой, true, false, nil), объявление анонимной функции, конструктор таблицы, обращение к переменной, вызов функции, vararg-выражение, выражения в круглых скобках, применённые к выражениям унарные операции и выражения, соединённые бинарными операциями.
У большинства выражений одно значение; вызовы функций и vararg-выражение могут иметь любое число значений. Обратите внимание, что если обернуть вызов функции или vararg-выражение в круглые скобки, будут отброшены все значения, кроме первого.
Списки выражений — разделённые запятыми последовательности выражений. Все выражения в списке, кроме последнего, приводятся к одному значению (лишние значения отбрасываются, а при отсутствии значений используется nil); все значения последнего выражения включаются в значения списка выражений.
Арифметические операции
Lua поддерживает обычный набор арифметических операций: сложение, вычитание, умножение, деление, остаток при делении, возведение в степень и отрицание.
Когда все операнды представлены или числами, или строками, для которых вызов tonumber() возвращает не nil, эти операции имеют обычный смысл.
Если какой-либо из операндов — таблица с соответствующим метаметод, этот метаметод будет вызван.
Операция | Функция | Пример | Метаметод | Замечания |
---|---|---|---|---|
+ | Сложение | a + b | __add | |
- | Вычитание | a - b | __sub | |
* | Умножение | a * b | __mul | |
/ | Деление | a / b | __div | деление на ноль не является ошибкой; будут возвращены NaN или бесконечность |
% | Остаток при делении | a % b | __mod | определяется как a % b == a - math.floor( a / b ) * b
|
^ | Возведение в степень | a ^ b | __pow | допускается не целочисленный показатель степени |
- | Отрицание | -a | __unm |
Операции сравнения
Операции сравнения в Lua — ==
, ~=
, <
, >
, <=
и >=
. Операции сравнения всегда возвращают булевы значения.
Равенство (==
) сначала сравнивает типы операндов, и если они различаются, возвращает false. Затем сравниваются значения: nil, булевы значения, числа и строки сравниваются по значению. Функции равны, только если они ссылаются на один и тот же объект функции; function() end == function() end
вернёт false, так как сравнивает две разные анонимные функции. Таблицы по умолчанию сравниваются так же, но это может быть изменено посредством метаметода __eq.
Неравенство (~=
) — логическое отрицание равенства.
В случае с операциями порядкового сравнения, два числа или две строки сравниваются напрямую. При иных операндах проверяются метаметоды:
a < b
использует__lt
a <= b
использует__le
, если доступен; иначе, если доступен__lt
, сравнение считается эквивалентнымnot ( b < a )
a > b
считается эквивалентнымb < a
a >= b
считается эквивалентнымb <= a
Если необходимые метаметоды отсутствуют, вызывается ошибка.
Логические операции
Логические операции — and
(и), or
(или) и not
(не). Все три используют интерпретацию, в которой nil и false считаются ложными, а все другие значения считаются истинными.
При использовании операции and
, если левый операнд считается ложным, он возвращается, а второй операнд не обрабатывается; иначе возвращается второй операнд.
При использовании операции or
, если левый операнд считается истинным, он возвращается, а второй операнд не обрабатывается; иначе возвращается второй операнд.
При использовании операции not
, результат всегда или true, или false.
Обратите внимание, что операции and
и or
не вычисляют значение правого операнда, если результат операции может быть определён только со знанием левого операнда. Например, foo() or bar()
вызовет функцию bar()
, только если функция foo()
вернёт как первое значение false или nil.
Операция конкатенации
Операция конкатенации — две точки. Он используется так: a .. b
. Если оба операнда — числа или строки, они преобразуются в строки и соединяются. В противном случае, если доступен метаметод __concat, будет использован он. Если и он не доступен, будет вызвана ошибка.
Обратите внимание: строки в Lua неизменяемые, и в Lua нет никакого «динамического конструктора строк». Поэтому если в цикле многократно операцию a = a .. b
, в каждой итерации будет создана новая строка, а старые через какое-то время будут удалены сборщиком мусора. При необходимости конкатенации большого количества строк может быть быстрее использовать string.format() или вставить нужные строки в последовательность и вызвать table.concat() после её построения.
Операция длины
Операция длины — #
. Он используется так: #a
. Если a
— строка, операция возвращает её длину в байтах. Если a
— таблица-последовательность, операция возвращает длину последовательности.
Если a
— таблица, не являющаяся последовательностью, #a
может вернуть 0 или любое такое значение, для которого a[N]
не равно nil, а a[N+1]
равно nil, даже если в таблице есть не равные nil значения с бо́льшими индексами. Например,
-- Это не последовательность, так как a[3] равно nil, а a[4] — нет
a = { 1, 2, nil, 4 }
-- Этот вызов может вывести как 2, так и 4.
-- И результат вызова может стать другим, даже если таблица не изменялась.
mw.log( #a )
Приоритетность операций
В Lua используется следующие правила о порядке выполнения (приоритете) операций, в порядке убывания приоритета:
- ^
- not # - (отрицание)
- * / %
- + - (вычитание)
- ..
- < > <= >= ~= ==
- and
- or
В пределах уровня приоритета, большинство бинарных операций левоассоциативно, т. е. a / b / c
интерпретируется как (a / b) / c
. Возведение в степень и конкатенация правоассоциативны, т. е. a ^ b ^ c
интерпретируется как a ^ (b ^ c)
.
Вызовы функций
В Lua, как и в большинстве других языков программирования, вызовы функций выглядят как название функции, за которым следует список аргументов в круглых скобках:
функция( список_выражений )
Как и при обычном использовании списков выражений в Lua, последнее выражение в списке может передавать функции несколько аргументов.
Если при вызове функции в списке выражений меньше значений, чем параметров в объявлении функции, дополнительные параметры будут иметь значение nil. Если в списке выражений больше значений, чем у функции параметров, лишние значения будут отброшены. Также возможно, что функция принимает переменное число аргументов; см. Объявления функций для подробной информации.
Lua также позволяет напрямую вызвать значение, возвращённое функцией, то есть func()()
. Если для определения вызываемой функции требуется более сложное выражение, чем обращение к переменной по названию, вместо этого обращения может быть использовано заключённое в круглые скобки выражение.
В Lua присутствует синтаксический сахар для двух распространённых вариантов вызова функций. Первый вариант — когда таблица используется как объект, а функция вызывается как метод этого объекта. Синтаксис
таблица:имя_функции( список_выражений )
в точности эквивалентен
таблица.имя_функции( таблица, список_выражений )
Второй вариант — способ, которым в Lua могут быть реализованы «именованные параметры» функций, а именно передача функции единственного аргумента — таблицы, содержащей нужные пары ключ-значение. При таком вызове круглые скобки вокруг списка аргументов могут быть опущены. Также они могут быть опущены, если функции передаётся один строковый литерал. Например, вызовы
func{ arg1 = exp, arg2 = exp } func"string"
эквивалентны вызовам
func( { arg1 = exp, arg2 = exp } ) func( "string" )
Эти два варианта могут использоваться одновременно; например, следующие вызовы функций эквивалентны:
table:name{ arg1 = exp, arg2 = exp } table.name( table, { arg1 = exp, arg2 = exp } )
Определение функций
Синтаксис определений функций выглядит так:
function nameoptional ( var-listoptional )
блок
end
Все переменные в списке список_переменных локальные для объявленной функции, а значения им присваиваются из списка выражений в вызове функции. В самом блоке функции могут быть объявлены ещё локальные переменные.
При вызове функции создаются и получают значения локальные переменные из списка список_переменных, а затем исполняются инструкции из блока блок. Если в блоке достигнут оператор return, выполнение блока завершается, а выражению вызова функции присваиваются значения, указанные в операторе return. Если достигнут конец блока, а оператор return не найден, результатом вызова функции является ноль значений.
Функции в Lua являются замыканиями. Нередко в области видимости, где объявляется какая-либо функция, также объявляются «внутренние статические» переменные, используемые этой функцией. Например,
-- Эта функция возвращает функцию, прибавляющую число к своему аргументу
function makeAdder( n )
return function( x )
-- Переменная n из внешней области видимости доступна здесь для добавления к x
return x + n
end
end
local add5 = makeAdder( 5 )
mw.log( add5( 6 ) )
-- выводит 11
Чтобы функция принимала переменное число аргументов, в её объявлении необходимо указать ...
как последний элемент в списке список_переменных:
В пределах блока может быть использовано varargs-выражение ...
, результатом которого будут все дополнительные аргументы, переданные функции. Например,
local join = function ( separator, ... )
-- получить дополнительные аргументы в виде новой таблицы
local args = { ... }
-- правильно подсчитать количество дополнительных аргументов
local n = select( '#', ... )
return table.concat( args, separator, 1, n )
end
join( ', ', 'foo', 'bar', 'baz' )
-- возвращает строку "foo, bar, baz"
Функция select() предназначена для работы с varargs-выражением; а именно, следует использовать select( '#', ... )
вместо #{ ... }
для подсчёта количества значений в varargs-выражении, так как { ... }
может не быть последовательностью.
Lua предоставляет синтаксический сахар для сочетания определения функции и присвоения её переменной; см. Операторы определения функции для подробной информации.
Обратите внимание, что этот код не будет работать:
local factorial = function ( n )
if n <= 2 then
return n
else
return n * factorial( n - 1 )
end
end
Так как определение функции обрабатывается до присвоения её локальной переменной, в теле функции factorial ссылается на (вероятно, неопределённую) переменную с этим именем из внешней области видимости. Этой проблемы можно избежать, если сначала объявить локальную переменную, а в следующей инструкции присвоить её значение этой функции. Также эта проблема не возникает при использовании синтаксиса оператора объявления функции.
Операторы
Оператор или инструкция (англ. statement) — наименьшая исполняемая единица программы: одно присваивание, одна управляющая структура, один вызов функции, одно объявление переменной, и т. п.
Фрагмент (англ. chunk) — последовательность инструкций, на усмотрение программиста разделённых точками с запятой. Фрагмент считается телом анонимной функции, так что он может объявлять локальные переменные, получать аргументы и возвращать значения.
Блок (англ. block) также является последовательностью инструкций, как и фрагмент. Блок может быть выделен в одну инструкцию: do блок end
. Такой подход может использоваться, чтобы ограничить область видимости локальных переменных, или чтобы добавить return
или break
в середину другого блока.
Присваивание
список_переменных = список_выражений
Список список_переменных — разделённый запятыми список переменных; список список_выражений — разделённый запятыми список из одного или более выражений. Значения всех выражений вычисляются до выполнения каких-либо присваиваний, поэтому при выполнении кода a, b = b, a
значения переменных a и b поменяются местами.
Объявление локальных переменных
local список_переменных
local список_переменных = список_выражений
Локальные переменные могут быть объявлены где угодно в пределах блока или фрагмента. Первая форма, не содержащая списка выражений, объявляет переменные, но не присваивает никаких значений; поэтому все переменные получат значение nil. Вторая форма присваивает значения локальным переменным, как описано в разделе Присваивание выше.
Обратите внимание, что область видимости локальной переменной начинается с инструкции, следующей за её объявлением. Поэтому объявление наподобие local x = x
объявит локальную переменную x и присвоит ей значение x из внешней области видимости. Локальная переменная остаётся видимой до завершения наиболее глубоко вложенного блока, содержащего её объявление.
Управляющие структуры
while выражение do блок end
Оператор while повторяет выполнение блока, пока указанное выражение принимает значение, считающееся истинным.
repeat блок until выражение
Оператор repeat повторяет выполнение блока до тех пор, пока указанное выражение не примет значение, считающееся истинным. Локальные переменные, объявленные блоки, могут использоваться в выражении цикла.
for имя = выражение1, выражение2, выражение3 do блок end
for имя = выражение1, выражение2 do блок end
Эта первая форма цикла for объявит локальную переменную и станет повторять выполнение блока для каждого значения переменной от выражение1 до выражение2 включительно, добавляя выражение3 после каждой итерации. Обратите внимание, что выражение3 может быть опущено, и в этом случае вместо него будет использовано значение 1; но если выражение3 содержит не числовое значение (например nil
или false
), будет вызвана ошибка. Значение всех выражений цикла вычисляется один раз перед началом цикла.
Эта форма цикла for примерно эквивалентна следующему коду:
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
но переменные var, limit и step не доступны в самом цикле. Обратите внимание, что переменная name локальная для блока цикла; чтобы использовать её значение после выполнения цикла, нужно скопировать его в переменную, объявленную вне цикла.
for список_переменных in список_выражений do блок end
Вторая форма цикла for работает с функциями-итераторами. Как и для первой формы, значение списка список_выражений вычисляется только один раз перед началом цикла.
Эта форма цикла for примерно эквивалентна следующему коду:
do
local func, static, var = expression-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
но, как и в примере для первого варианта, переменные func, static, and var не доступны в самом цикле. Обратите внимание, что переменные в списке список_переменных локальны для блока цикла; чтобы использовать их значения после цикла, нужно скопировать их в переменные, объявленные вне цикла.
Нередко список_выражений представлен одним вызовом функции, возвращающим нужные три значения. Наиболее эффективна такая функция-итератор, которая зависит только от предоставленных ей аргументов. На случай, если это невозможно, авторы книги Programming in Lua считают, что предпочтительнее создавать замыкание, чем возвращать таблицу как статическую переменную и обновлять её поля каждую итерацию.
if выражение1 then блок1 elseif выражение2 then блок2 else блок3 end
Если выражение1 истинно, исполняет блок1, иначе если выражение2 истинно, исполняет блок2, в противном случае исполняет блок3. Часть кода else блок3
может быть опущена, а часть кода elseif выражение2 then блок2
может быть повторена несколько раз с разными выражениями и блоками или же может отсутствовать.
return список_выражений
Оператор return используется для того, чтобы возвращать значения из функции или из фрагмента (который, по существу, тоже является функцией). список_выражений — разделённый запятыми список из нуля или более выражений.
В Lua реализована оптимизация хвостовой рекурсии: если список_выражений состоит из единственного выражения, являющегося вызовом функции, для вызова функции будет использован уже имеющийся стековый фрейм. Эта оптимизация влияет на функции, работающие со стеком вызовов, включая getfenv()
и debug.traceback()
.
Оператор return должен быть последним в своём блоке. Если по какой-то причине return нужен посередине блока, можно создать явный блок оператором do return end
.
break
Оператор break используется для прекращения выполнения цикла while, repeat или for и перехода к оператору, следующему после цикла.
Оператор break должен быть последним в своём блоке. Если по какой-то причине break нужен посередине блока, можно создать явный блок оператором do break end
.
Unlike some other languages, Lua does not have a "continue" statement for loops (i.e. a statement to move onto the next iteration without breaking the loop altogether).
It is straightforward to achieve the same effect by nesting a repeat ... until true
block immediately inside the main loop, which will only ever iterate once for each iteration of the main loop (as its condition is always true).
Using break
will only end the inner loop, which has the practical effect of causing the main loop to continue onto the next iteration.
If it is necessary to use break
on the main loop, simply declare a variable which is checked each time the inner loop completes, and set it when necessary.
Вызовы функций как инструкции
Вызов функции может быть использован как инструкция. В таком случае функция вызывается только ради её побочных эффектов (например, mw.log() записывает переданные ей значения в журнал), а возвращённые ей значения отбрасываются.
Операторы объявления функции
Lua предоставляет синтаксический сахар, чтобы объявление функций, их определение и назначение им имени выглядело более естественно. Следующие пары объявлений функций эквивалентны:
-- Основное объявление function func( var-list ) block end func = function ( var-list ) block end
-- Локальная функция local function func( var-list ) block end local func; func = function ( var-list ) block end
-- Функция как поле в таблице function table.func( var-list ) block end table.func = function ( var-list ) block end
-- Функция как метод в таблице function table:func( var-list ) block end table.func = function ( self, var-list ) block end
Заметьте, что приведённая выше запись с двоеточием соответствует использованию двоеточия при вызове функций. При объявлении функции с использованием двоеточия добавляется неявный параметр «self
», предшествующий явному списку параметров.
Обработка ошибок
Ошибки могут быть сгенерированы вызовом функций error() и assert(). Чтобы обработать ошибку, используйте функции pcall() или xpcall(). Обратите внимание, что некоторые внутренние ошибки Scribunto не могут быть обработаны в пределах модулей Lua.
Сборка мусора
Управление памятью Lua производит автоматически. Ввиду этого вам не нужно беспокоиться ни о выделении памяти под новые объекты, ни об освобождение памяти, когда какие-либо объекты станут ненужными. Lua периодически запускает сборщик мусора для удаления всех объектов, которые больше не будут востребованы программой (обращение к которым из Lua больше невозможно), а также объектов, которые доступны только по слабым ссылкам. Вся используемая Lua память (таблицы, функции, строки, и т. п.) управляется автоматически.
Сборка мусора происходит автоматически и не может быть настроена в коде модулей Scribunto.
Стандартные библиотеки
Стандартные библиотеки Lua предоставляют модулям наиболее важные возможности, а также функции, где производительность критична. Ниже документированы только те функции, которые доступны в Scribunto.
Основные функции
_G
Эта переменная хранит ссылку на текущую таблицу глобальных переменных; к глобальной переменной foo
можно обратиться выражением _G.foo
. Обратите внимание, что сама таблица _G не отличается от обычных таблиц, и ей может быть присвоено другое значение, как и любой другой переменной:
foo = 1
mw.log( foo ) -- logs "1"
_G.foo = 2
mw.log( foo ) -- logs "2"
_G = {} -- _G больше не указывает на таблицу глобальных переменных
_G.foo = 3
mw.log( foo ) -- still logs "2"
Таблица глобальных переменных может быть использована, как и любая другая таблица. Например,
-- Вызвать функцию, имя которой хранится в переменной
_G[var]()
-- Записывать имена и строковые значения всех глобальных переменных
for k, v in pairs( _G ) do
mw.log( k, v )
end
-- Записывать создание новых глобальных переменных
setmetatable( _G, {
__newindex = function ( t, k, v )
mw.log( "Creation of new global variable '" .. k .. "'" )
rawset( t, k, v )
end
} )
_VERSION
Строка, содержащая текущую версию Lua, например "Lua 5.1".
assert
assert( v, message, ... )
Если v
равно nil или false, генерирует ошибку. В этом случае message
будет использоваться как текст ошибки: если он равен nil (или не указан), будет использоваться текст "assertion failed!"; если он является строкой или числом, это значение будет использоваться как текст; в противном случае функция assert сама сгенерирует ошибку.
Если v
не является ни nil, ни false, assert вернёт все переданные ей аргументы, включая v
и message
.
В Lua нередко используются функции, при нормальном выполнении возвращающие истинное значение, а в случае сбоя возвращающие как первое значение nil или false, а как второе — сообщение об ошибке. Успешное выполнение такой функции можно легко проверить, обернув её вызов в вызов функции assert
:
-- Это не проверяет наличие ошибок
local result1, result2, etc = func( ... )
-- Это работает так же, но проверяет наличие ошибок
local result1, result2, etc = assert( func( ... ) )
error
error( message, level )
Генерирует ошибку с текстом message
.
error
обычно добавляет дополнительную информацию о месте, где возникла ошибка. Если level
равен 1 или опущен, это место — сам вызов error
; при значении 2 используется место вызова функции, вызвавшей error; и так далее. Если level
равен 0, информация о месте возникновения ошибки приведена не будет.
getfenv
getfenv( f )
Обратите внимание, что эта функция может не быть доступна в зависимости от того, как задана переменная allowEnvFuncs
в конфигурации движка.
Возвращает окружение (таблицу глобальных переменных) в зависимости от значения f
:
- При значении 1, nil, или отсутствии значения, будет возвращено окружение функции, вызвавшей
getfenv
. Нередко это окружение будет таким же, как _G. - Если значение — целые число от 2 до 10 включительно, будет возвращено окружение функции, лежащей глубже в стеке вызовов. Например, при значении 2
getfenv
вернёт окружение функции, вызвавшей функцию, вызвавшуюgetfenv
, при значении 3getfenv
вернёт окружение функции, окружение которой возвращается при значении 2, и так далее. Будет сгенерирована ошибка, если указано значение большее, чем количество вызовов функций в стеке, или если на указанной глубине стека произошёл возврат с хвостовой рекурсией. - Если значение — функция, будет возвращено окружение, которые будет использовано при вызове этой функции.
Окружения, используемые всеми функциями из стандартных библиотек и библиотек Scribunto, защищены. При попытке получить доступ к этим окружениям с помощью getfenv
будет возвращено значение nil.
getmetatable
getmetatable( table )
Возвращает метатаблицу переданной функции таблицы. Если функции передано значение любого другого типа, она вернёт nil.
Если в метатаблице есть поле __metatable
, вместо настоящей метатаблицы будет возращено значение этого поля.
ipairs
ipairs( t )
Возвращает три значения: функцию-итератор, таблицу t
и 0. Эта функция предназначена для использования в итераторной форме цикла for
:
for i, v in ipairs( t ) do
-- process each index-value pair
end
При выполнении этого кода цикл будет итерировать по парам значений ( 1, t[1] ), ( 2, t[2] ) и так далее до тех пор, пока t[i] не станет равно nil.
Стандартное поведение функции может быть переопределено, если у предоставленного значения есть метаметход __ipairs
. Если этот метаметод задан, вызов ipairs вернёт вместо обычных значений три значения, возвращённые вызовом __ipairs( t )
.
next
next( table, key )
Эта функция позволяет итерировать по ключам таблицы. Если key
равен nil или не указан, функция возвращает «первый» ключ таблицы и соответствующее ему значение; в противном случае функция возвращает «следующий» ключ таблицы и соответствующее значение. Когда ключей больше не осталось, функция возвращает nil. Вызовом next( t ) == nil
можно проверить, пуста ли таблица.
Обратите внимание, что порядок, в котором возвращаются ключи, не определён, даже для таблиц с числовыми ключами. Чтобы обработать таблицу в числовом порядке, используйте числовой цикл for или функцию ipairs.
Поведение функции next не определено, если при обходе таблицы этой функцией в таблице присвоено значение ранее отсутствовавшему ключу. Присвоение значения (в том числе nil) существующему полю не вызывает проблем.
pairs
pairs( t )
Возвращает три значения: функцию-итератор (next или работающую по схожим принципам), таблицу t
и nil. Эта функция предназначена для использования в итераторной форме цикла for
:
for k, v in pairs( t ) do
-- обрабатывать каждую пару ключ-значение
end
При выполнении этого цикла программа будет итерировать по парам ключ-значение в t
так же, как функция next; обратитесь к документации по next для информации об ограничениях на изменение таблицы во время её обхода.
Стандартное поведение функции может быть переопределено, если у предоставленного значения есть метаметод __pairs. Если этот метаметод задан, вызов pairs вернёт вместо обычных значений три значения, возвращённые вызовом __pairs( t )
.
pcall
pcall( f, ... )
Вызывает функцию f
с предоставленными аргументами в защищённом режиме. Это значит, что если при вызове f
будет сгенерирована ошибка, pcall вернёт false и текст ошибки. Если ошибки не возникнет, pcall вернёт true и все значения, возвращённые вызовом.
В псевдокоде pcall
может быть определена примерно так:
function pcall( f, ... )
try
return true, f( ... )
catch ( message )
return false, message
end
end
rawequal
rawequal( a, b )
Эта функция эквивалентна операции a == b
, но в отличие от неё игнорирует метаметод __eq.
rawget
rawget( table, k )
Эта функция эквивалентна операции table[k]
, но в отличие от неё игнорирует метаметод __index.
rawset
rawset( table, k, v )
Эта функция эквивалентна операции table[k] = v
, но в отличие от неё игнорирует метаметод __newindex.
select
select( index, ... )
Если index
— число, возвращает все аргументы из ...
с индексом больше этого числа. Если index
— строка '#', возвращает количество аргументов в ...
.
Другими словами, select
работает примерно так, как код ниже, но корректно обрабатывает случаи, когда некоторые значения в ...
равны nil (о проблемах с nil см. документацию по # и unpack).
function select( index, ... )
local t = { ... }
if index == '#' then
return #t
else
return unpack( t, index )
end
end
setmetatable
setmetatable( table, metatable )
Задаёт метатаблицу заданной таблицы. metatable
может быть равен nil, но должен быть указан явно.
Если в текущей метатаблице содержится поле __metatable, setmetatable
сгенерирует ошибку.
tonumber
tonumber( value, base )
Попытается преобразовать value
в число. Если оно уже число, или строка, преобразовываемая к числу, tonumber
возвращает это число. В противном случае функция вернёт nil.
Необязательный параметр base
(по умолчанию равный 10) определяет основание системы счисления, в которой интерпретируется число. Основание может быть от 2 до 36, включая оба этих значения. Если основание больше 11, для разряда со значением 10 используется латинская буква 'A' (в любом регистре), для значения 11 — буква 'B', и так далее; для значения 35 используется буква 'Z'.
Если основание равно 10, у значения может быть дробная часть, оно может выражаться экспоненциальной записью; также в начале значения может присутствовать "0x" для указания шестнадцатеричного числа. Если основание не равно 10, значение должно быть беззнаковым целым.
tostring
tostring( value )
Преобразовывает value
в строку. См. раздел Типы данных выше для подробностей о преобразовании разных типов данных.
Стандартное поведение функции для таблиц может быть переопределено, если у таблицы есть метаметод __tostring. Если этот метаметод задан, вызов tostring вернёт единственное значение, возвращённое вызовом __tostring( value )
.
type
type( value )
Возвращает строку, указывающую тип value
: "nil"
, "number"
, "string"
, "boolean"
, "table"
или "function"
.
unpack
unpack( table, i, j )
Возвращает значения из заданной таблицы, примерно как делал бы это код table[i], table[i+1], ···, table[j]
. Если эти параметры равны nil или не указаны, i
считается равным 1, а j
считается равным #table
.
Обратите внимание, что результаты не определены, если table
— не последовательность, а j
равен nil или не указан; см. раздел Операция длины для более подробной информации.
xpcall
xpcall( f, errhandler )
Эта функция аналогична функции pcall
, но возвращаемое сообщение об ошибке предварительно передаётся функции errhandler
.
В псевдокоде xpcall
может быть определена примерно так:
function xpcall( f, errhandler )
try
return true, f()
catch ( message )
message = errhandler( message )
return false, message
end
end
Библиотека Debug
debug.traceback
debug.traceback( message, level )
Возвращает строку с трассировкой стека вызовов. Перед началом трассировки может быть приведена необязательная строка message. Необязательное число level может быть использовано для того, чтобы указать, с какого уровня стека начать трассировку.
Библиотека Math
math.abs
math.abs( x )
Возвращает абсолютную величину (модуль) числа x
.
math.acos
math.acos( x )
Возвращает арккосинус числа x
(приведённого в радианах).
math.asin
math.asin( x )
Возвращает арксинус числа x
(приведённого в радианах).
math.atan
math.atan( x )
Возвращает арктангенс числа x
(приведённого в радианах).
math.atan2
math.atan2( y, x )
Возвращает арктангенс выражения (параметры приведены в радианах). Для определения, в какой четверти лежит результат, используются знаки обоих аргументов.
math.ceil
math.ceil( x )
Возвращает наименьшее целое число, которое больше или равно x
.
math.cos
math.cos( x )
Возвращает косинус числа x
(приведённого в радианах).
math.cosh
math.cosh( x )
Возвращает гиперболический косинус числа x
.
math.deg
math.deg( x )
Возвращает угол x
(приведённый в радианах) в градусах.
math.exp
math.exp( x )
Возвращает значение .
math.floor
math.floor( x )
Возвращает наибольшее целое число, которое меньше или равно x
.
math.fmod
math.fmod( x, y )
Возвращает остаток от деления с остатком x
на y
. Например, вызов math.fmod( 10, 3 )
вернёт 1
.
math.frexp
math.frexp( x )
Возвращает такие два значения m
и e
, что:
- Если
x
— конечное число, не равное нулю: , гдеe
— целое число, а абсолютная величинаm
лежит в промежутке . - Если
x
равно нулю:m
иe
равны 0. - Если
x
равно NaN или бесконечности:m
равноx
,e
не приводится.
math.huge
Значение, представляющее собой положительную бесконечность; оно больше или равно любому другому числовому значению.
math.ldexp
math.ldexp( m, e )
Возвращает (e
должно быть целым числом).
math.log
math.log( x )
Возвращает натуральный логарифм числа x
.
math.log10
math.log10( x )
Возвращает десятичный логарифм числа x
.
math.max
math.max( x, ... )
Возвращает наибольшее значение из приведённых аргументов.
Если среди аргументов есть значения NaN, поведение функции не определено. Текущая реализация возвращает NaN, если x
равен NaN, но все остальные NaN будут проигнорированы.
math.min
math.min( x, ... )
Возвращает наименьшее значение из приведённых аргументов.
Если среди аргументов есть значения NaN, поведение функции не определено. Текущая реализация возвращает NaN, если x
равен NaN, но все остальные NaN будут проигнорированы.
math.modf
math.modf( x )
Возвращает два числа: целую часть x
и дробную часть x
. Например, вызов math.modf( 1.25 )
вернёт 1, 0.25
.
math.pi
Значение .
math.pow
math.pow( x, y )
Эквивалентно выражению x^y
.
math.rad
math.rad( x )
Возвращает угол x
(приведённый в градусах) в радианах.
math.random
math.random( m, n )
Возвращает псевдослучайное число.
Параметры m
и n
могут быть опущены, но если они указаны, они должны быть приводимы к целым числам.
- Если аргументов нет, возвращает вещественное число в промежутке .
- Если приведён один аргумент, возвращает целое число в промежутке .
- Если приведено два аргумента, возвращает целое число в промежутке .
Note that incorrect output may be produced if m
or n
are less than −2147483648 or greater than 2147483647, or if n - m
is greater than 2147483646.
math.randomseed
math.randomseed( x )
Задаёт x
как зерно для генератора псевдослучайных чисел.
Обратите внимание, что при использовании одного и того же зерна math.random
будет возвращать одну и ту же последовательность чисел.
math.sin
math.sin( x )
Возвращает синус числа x
(приведённого в радианах).
math.sinh
math.sinh( x )
Возвращает гиперболический синус числа x
.
math.sqrt
math.sqrt( x )
Возвращает квадратный корень числа x
. Эквивалентна x^0.5
.
math.tan
math.tan( x )
Возвращает тангенс числа x
(приведённого в радианах).
math.tanh
math.tanh( x )
Возвращает гиперболический тангенс числа x
.
Библиотека функций ОС
os.clock
os.clock()
Возвращает приближённое значение задействованного программой времени центрального процессора в секундах.
os.date
os.date( format, time )
- Функция formatDate из библиотеки lang предоставляет более полные средства форматирования дат.
Возвращает строку или таблицу, содержащую дату и время, отформатированные согласно значению параметра format
. Если этот параметр опущен или равен nil, используется значение "%c".
Если указан параметр time
, будет отформатировано это время (см. os.time()
). В противном случае будет использовано текущее время.
Если format
начинается с символа '!', то дата форматируется в часовом поясе UTC, а не с использованием локального времени сервера. Если, без учёта символа '!', формат — строка "*t", функция date возвращает таблицу со следующими полями:
- year — год (полностью)
- month — месяц (1–12)
- day — день (1–31)
- hour — час (0–23)
- min — минута (0–59)
- sec — секунда (0–59) (исключение: дополнительная секунда = 60)
- wday — день недели (воскресенье — 1)
- yday — день года
- isdst — флаг летнего времени, булево значение; может отсутствовать, если информация об использовании летнего времени недоступна.
Если формат не равен "*t", функция date вернёт дату как строку, отформатированную по тем же правилам, что и функция языка C strftime.
os.difftime
os.difftime( t2, t1 )
Возвращает количество секунд от t1
до t2
.
os.time
os.time( table )
Возвращает число, представляющее текущее время.
При вызове без аргументов возвращает текущее время. Если функции передана таблица, будет обработано время, представленное таблицей. В таблице должны быть поля "year" (год), "month" (месяц) и "day" (день); в ней также могут присутствовать поля "hour" (час, по умолчанию 12), "min" (минута, по умолчанию 0), "sec" (секунда, по умолчанию 0) и "isdst".
Библиотека Package
require
require( modulename )
Загружает указанный модуль.
Сначала функция обращается к package.loaded[modulename]
, проверяя, загружен ли уже этот модуль. Если он загружен, возвращает package.loaded[modulename]
.
Если модуль не загружен, функция вызывает каждый загрузчик в последовательности package.loaders
, пытаясь найти тот, который загрузит модуль. Если такой загрузчик удастся найти, функция вызовет его. Значение, возвращённое загрузчиком, записывается в package.loaded[modulename]
и возвращается.
Обратитесь к документации для package.loaders
с целью получения информации о доступных загрузчиках.
Например, если у вас есть модуль "Module:Giving", содержащий следующий код:
local p = {}
p.someDataValue = 'Привет!'
return p
Вы можете загрузить его в другом модуле, использовав такой код:
local giving = require( "Module:Giving" )
local value = giving.someDataValue -- value теперь равно 'Привет!'
package.loaded
В этой таблице хранятся загруженные модули. Ключи — названия модулей, а значения — то, что было возвращено при загрузке модуля.
package.loaders
В этой таблице содержится последовательность функций поиска, используемых при загрузке модулей. Каждая функция поиска вызывается с одним аргументом - именем загружаемого модуля. Если модуль найден, поисковик должен вернуть функцию, которая фактически загрузит модуль и вернет значение, возвращаемое функцией require. В противном случае он должен вернуть ноль.
Scribunto предоставляет два средства поиска:
- Поиск в
package.preload [modulename]
функции загрузчика - Поиск в модулях, поставляемых с Scribunto имени модуля, и если это не помогло, посмотрите в пространстве имен Module :. Необходимо указать префикс «Модуль:».
Обратите внимание, что стандартные загрузчики Lua не включены.
package.preload
Эта таблица содержит функции загрузчика, используемые первым искателем, который Scribunto включает в package.loaders.
package.seeall
package.seeall( table )
Устанавливает __index метаметод для таблицы
в _G.
Библиотека String
Во всех строковых функциях первый символ находится в позиции 1, а не в позиции 0, как в C, PHP и JavaScript. Индексы могут быть отрицательными, и в этом случае они отсчитываются от конца строки: позиция -1 - последний символ в строке, -2 - второй последний и т. Д.
Warning: Библиотека строк предполагает однобайтовые кодировки символов. Он не может обрабатывать символы Юникода. Чтобы работать со строками Unicode, используйте соответствующие методы в библиотеке Scribunto Ustring.
string.byte
string.byte( s, i, j )
Если строка рассматривается как массив байтов, возвращает байтовые значения для s[i]
, s[i+1]
, ···, s[j]
.
Значение по умолчанию для i
— 1;
Значение по умолчанию для j
— i
.
Идентично mw.ustring.byte().
string.char
string.char( ... )
Получает ноль или более целых чисел. Возвращает строку с длиной, равной количеству аргументов, в которой каждый символ имеет байтовое значение, равное его соответствующему аргументу.
local value = string.char( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21 ) --value теперь равно 'Hello!'
См. mw.ustring.char() о схожей функции, которая использует символы Юникода, а не байты.
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.
See mw.ustring.find() for a similar function extended as described in Ustring patterns and where the init
offset is in characters rather than bytes.
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.
Аналогично mw.ustring.format().
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.
See mw.ustring.gmatch() for a similar function for which the pattern is extended as described in Ustring patterns.
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 %d
,
with d between 1 and 9, stands for the value of the d-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).
See mw.ustring.gsub() for a similar function in which the pattern is extended as described in Ustring patterns.
string.len
string.len( s )
Returns the length of the string, in bytes. Is not confused by ASCII NUL characters. Equivalent to #s
.
См. mw.ustring.len() о схожей функции, которая использует символы Юникода, а не байты.
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.
See mw.ustring.lower() for a similar function in which all characters with uppercase to lowercase definitions in Unicode are converted.
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.
See mw.ustring.match() for a similar function in which the pattern is extended as described in Ustring patterns and the init
offset is in characters rather than bytes.
string.rep
string.rep( s, n )
Returns a string that is the concatenation of n
copies of the string s
. Identical to mw.ustring.rep().
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, it will continue until the end of the string.
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
.
See mw.ustring.sub() for a similar function in which the offsets are characters rather than bytes.
string.ulower
string.ulower( s )
An alias for mw.ustring.lower().
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.
See mw.ustring.upper() for a similar function in which all characters with lowercase to uppercase definitions in Unicode are converted.
string.uupper
string.uupper( s )
An alias for mw.ustring.upper().
Паттерны
Note that Lua's patterns are similar to regular expressions, but are not identical. In particular, note the following differences from regular expressions and PCRE:
- В качестве символа экранирования используется процент (
%
), а не обратный слэш (\
). - Точка (
.
) всегда соответствует любым символам, включая перевод строки. - Отсутствует регистронезависимый режим.
- Отсутствует перебор вариантов (оператор
|
) - Квантификаторы (
*
,+
,?
и-
) могут применяться только к отдельным символам, а не группам захвата. - Единственным нежадным квантификатором является
-
, аналог квантификатора*?
из PCRE.
- No generalized finite quantifier (e.g. the
{n,m}
quantifier in PCRE).
- The only zero-width assertions are
^
,$
, and the%f[set]
"frontier" pattern; assertions such as PCRE's\b
or(?=···)
are not present.
- Patterns themselves do not recognize character escapes such as "\ddd". However, since patterns are strings these sort of escapes may be used in the string literals used to create the pattern-string.
Also note that a pattern cannot contain embedded zero bytes (ASCII NUL, "\0"
). Use %z
instead.
Also see Ustring patterns for a similar pattern-matching scheme using Unicode characters.
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
|
Соответствует всем буквам ASCII. |
%c
|
Соответствует всем управляющим символам ASCII. |
%d
|
Соответствует всем цифрам. |
%l
|
Соответствует всем строчным буквам ASCII. |
%p
|
Соответствует всем знакам пунктуации. |
%s
|
Соответствует всем пробельным символам ASCII. |
%u
|
Соответствует всем заглавным буквам ASCII. |
%w
|
Represents all ASCII alphanumeric characters. |
%x
|
Represents all hexadecimal digits. |
%z
|
Represents ASCII NUL, the zero byte. |
%A
|
Все символы не в %a .
|
%C
|
Все символы не в %c .
|
%D
|
Все символы не в %d .
|
%L
|
Все символы не в %l .
|
%P
|
Все символы не в %p .
|
%S
|
Все символы не в %s .
|
%U
|
Все символы не в %u .
|
%W
|
Все символы не в %w .
|
%X
|
Все символы не в %x .
|
%Z
|
Все символы не в %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 ' The interaction between ranges and classes is not defined. Therefore, patterns like |
[^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.
%f[set]
, a frontier pattern; such item matches an empty string at any position such that the next character belongs to set and the previous character does not belong to set. The set set is interpreted as previously described. The beginning and the end of the subject are handled as if they were the character '\0'.
Note that frontier patterns were present but undocumented in Lua 5.1, and officially added to Lua in 5.2. The implementation in Lua 5.2.1 is unchanged from that in 5.1.0.
Паттерн
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.
Capture references can appear in the pattern string itself, and refer back to text that was captured earlier in the match. For example, ([a-z])%1
will match any pair of identical lowercase letters, while ([a-z])([a-z])([a-z])[a-z]%3%2%1
will match any 7-letter palindrome.
As a special case, the empty capture ()
captures the current string position (a number). For instance, if we apply the pattern "()aa()"
on the string "flaaap"
, there will be two captures: 3 and 5.
Known limitations: Unlike Ustring library patterns, String library patterns may not contain more than 32 captures. If the pattern has more, then the String function will throw an error. Because the Ustring library has its own maximum of 10,000 bytes for patterns (unlike the String library), it is therefore impossible to use a pattern which exceeds both limits, as it will be incompatible with both libraries.
Библиотека Table
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. The function table.setn()
is completely obsolete, however, and will throw an error if used.
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 an 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
, it returns an 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
Все библиотеки Scribunto находятся в таблице mw
.
Основные функции
mw.addWarning
mw.addWarning( text )
Добавляет предупреждение, которое отображается над окном предварительного просмотра редактирования. text
анализируется как викитекст.
mw.allToString
mw.allToString( ... )
Вызывает tostring() для всех аргументов, а затем объединяет их с символами табуляции в качестве разделителей.
mw.clone
mw.clone( value )
Создает глубокую копию значения. Все таблицы (и их метатаблицы) востановленны с нуля. Однако функции по-прежнему являются общими.
mw.getCurrentFrame
mw.getCurrentFrame()
Возвращает текущий объект frame, обычно объект frame из самого последнего #invoke
.
mw.incrementExpensiveFunctionCount
mw.incrementExpensiveFunctionCount()
Добавляет к "expensive parser function" количество вызовов, и выдает исключение если оно превышает лимит (см. $wgExpensiveParserFunctionLimit
).
mw.isSubsting
mw.isSubsting()
Возвращает true, если текущий #invoke
является подстановкой, в противном случае false. См. раздел Возвращаемый текст выше, для рассмотрения различий между подстановкой и не подстановкой.
mw.loadData
mw.loadData( module )
Иногда модулю требуются большие таблицы данных; например, модулю общего назначения для преобразования единиц измерения может потребоваться большая таблица распознанных единиц измерения и их коэффициентов пересчета. И иногда эти модули будут использоваться много раз на одной странице. Разбор большой таблицы данных для каждого {{#invoke:}}
может занять значительное количество времени. Чтобы избежать этой проблемы, предоставляется mw.loadData()
.
mw.loadData
работает также как require()
, со следующими отличиями:
- Загруженный модуль вычисляется только один раз на странице, а не каждый раз при вызове
{{#invoke:}}
. - Загруженный модуль не записывается в
package.loaded
. - Значение, возвращаемое загруженным модулем, должно быть таблицей. Другие типы данных не поддерживаются.
- Возвращаемая таблица (и все подтаблицы) могут содержать только логические значения, числа, строки и другие таблицы. Другие типы данных, в частности, функции, не допускаются.
- Возвращаемая таблица (и все подтаблицы) могут не иметь метатаблиц. SMS
- Все ключи таблицы должны быть логическими, числовыми или строковыми.
- The table actually returned by
mw.loadData()
has metamethods that provide read-only access to the table returned by the module. Since it does not contain the data directly,pairs()
andipairs()
will work but other methods, including#value
,next()
, and the functions in the Table library, will not work correctly.
Упомянутый выше гипотетический модуль преобразования единиц измерения, может хранить код в "Module:Convert", а данные в "Module:Convert/data" и "Module:Convert" будет использовать local data = mw.loadData( 'Module:Convert/data' )
для эффективной загрузки данных.
mw.loadJsonData
mw.loadJsonData( page )
This is the same as mw.loadData()
above, except it loads data from JSON pages rather than Lua tables.
The JSON content must be an array or object.
See also mw.text.jsonDecode()
.
mw.dumpObject
mw.dumpObject( object )
Сериализует object
в удобочитаемое представление, а затем возвращает полученную строку.
mw.log
mw.log( ... )
Передает аргументы в mw.allToString(), затем добавляет полученную строку в буфер лога.
В консоли отладки функция print()
является псевдонимом для этой функции.
mw.logObject
mw.logObject( object )
mw.logObject( object, prefix )
Вызывает mw.dumpObject() и добавляет полученную строку в буфер лога. Если указан префикс prefix
, то он будет добавлен в буфер лога со знаком равенства перед добавлением сериализованной строки (т.е. записываемый текст будет "prefix = object-string").
Объект Frame
Объект frame - это интерфейс для параметров, переданных в {{#invoke:}}
.
Note that there is no frame library, and there is no global variable named frame
. A frame object is typically obtained by being passed as a parameter to the function called by {{#invoke:}}
, and can also be obtained from mw.getCurrentFrame()
.
frame.args
Таблица для доступных аргументов переданных во frame. Например, если модуль вызывается из викитекста с
{{#invoke:module|function|arg1|arg2|name=arg3}}
то frame.args[1]
будет возвращать "arg1"
, frame.args[2]
будет возвращать "arg2"
, и frame.args['name']
(или frame.args.name
) будет возвращать "arg3"
. Также можно перебирать аргументы с помощью pairs( frame.args )
или ipairs( frame.args )
.
However, due to how Lua implements table iterators, iterating over arguments will return them in an unspecified order, and there's no way to know the original order as they appear in wikitext.
Обратите внимание, что значения в этой таблице всегда строки; tonumber()
может использоваться для преобразования их в числа, если это необходимо. Однако ключи являются числами, даже если явно предоставлено в вызове: {{#invoke:module|function|1|2=2}}
дает строковые значения "1"
и "2"
индексируется цифровыми ключами 1
и 2
.
Как и в вызовах шаблонов MediaWiki, у именованных аргументов будут удаленны начальные и конечные пробелы, как из имени, так и из значения, прежде чем они будут переданы Lua. В то время как у безымянных аргументов пробелы не будут удалены.
Для большей производительности, frame.args
использует метатаблицу, а не непосредственно содержащую аргументы. Значения аргументов запрашиваются у MediaWiki по требованию. Это означает, что большинство других методов таблицы будут работать неправильно, включая #frame.args
, next( frame.args )
, и функции в Table library.
Если в аргументе для #invoke содержатся команды препроцессора, например вызовы шаблонов и параметры в тройных скобках, они разворачиваются только тогда, когда значение аргумента будет запрошено из Lua. Если в аргументе присутствуют некоторые XML-теги, такие как <pre>
, <nowiki>
, <gallery>
и <ref>
, то они будут преобразованы в "strip markers" — специальные строки, начинающиеся с символа delete (ASCII 127), которые после возврата из #invoke заменяются на HTML.
frame:callParserFunction
frame:callParserFunction( name, args )
frame:callParserFunction( name, ... )
frame:callParserFunction{ name = string, args = table }
- Note the use of named arguments.
Call a parser function, returning an appropriate string. This is preferable to frame:preprocess
, but whenever possible, native Lua functions or Scribunto library functions should be preferred to this interface.
The following calls are approximately equivalent to the indicated wikitext:
-- {{ns:0}}
frame:callParserFunction( 'ns', { 0 } )
frame:callParserFunction( 'ns', 0 )
frame:callParserFunction{ name = 'ns', args = { 0 } }
-- {{#tag:nowiki|some text}}
frame:callParserFunction( '#tag', { 'nowiki', 'some text' } )
frame:callParserFunction( '#tag', 'nowiki', 'some text' )
frame:callParserFunction( '#tag:nowiki', 'some text' )
frame:callParserFunction{ name = '#tag', args = { 'nowiki', 'some text' } }
-- {{#tag:ref|some text|name=foo|group=bar}}
frame:callParserFunction( '#tag', { 'ref',
'some text', name = 'foo', group = 'bar'
} )
Note that, as with frame:expandTemplate(), the function name and arguments are not preprocessed before being passed to the parser function.
frame:expandTemplate
frame:expandTemplate{ title = title, args = table }
- Note the use of named arguments.
This is transclusion. The call:
frame:expandTemplate{ title = 'template', args = { 'arg1', 'arg2', name = 'arg3' } }
does roughly the same thing from Lua that {{template|arg1|arg2|name=arg3}}
does in wikitext. As in transclusion, if the passed title does not contain a namespace prefix it will be assumed to be in the Template: namespace.
Note that the title and arguments are not preprocessed before being passed into the template:
-- This is roughly equivalent to wikitext like {{template|{{!}}}}
frame:expandTemplate{ title = 'template', args = { '|' } }
-- This is roughly equivalent to wikitext like {{template|{{((}}!{{))}}}}
frame:expandTemplate{ title = 'template', args = { '{{!}}' } }
frame:extensionTag
frame:extensionTag( name, content, args )
frame:extensionTag{ name = string, content = string, args = table_or_string }
This is equivalent to a call to frame:callParserFunction() with function name '#tag'
(see Help:Magic_words#Miscellaneous) and with name
and content
prepended to args
.
-- These are equivalent
frame:extensionTag( 'ref', 'some text', { name = 'foo', group = 'bar' } )
frame:extensionTag{ name = 'ref', content = 'some text', args = { name = 'foo', group = 'bar' } }
frame:callParserFunction( '#tag', { 'ref' ,
'some text', name = 'foo', group = 'bar'
} )
-- These are equivalent
frame:extensionTag{ name = 'ref', content = 'some text', args = { 'some other text' } }
frame:callParserFunction( '#tag', { 'ref',
'some text', 'some other text'
} )
frame:getParent
frame:getParent()
Вызывается на объекте frame, созданным {{#invoke:}}
, возвращает frame для страницы, которая вызвала {{#invoke:}}
. Будучи вызвана на этом фрейме, вернет nil.
Например, если шаблон {{Example}}
содержит код {{#invoke:ModuleName}}
, а при вызове этого шаблона в него передаются аргументы ({{Example|arg1|arg2}}
),то код mw.getCurrentFrame():getParent().args[1], mw.getCurrentFrame():getParent().args[2]
записанный в Модуле:ModuleName вернет "arg1", "arg2"
.
frame:getTitle
frame:getTitle()
Возвращает заголовок в виде строки связанный с фреймом. Для фрейма созданного {{#invoke:}}
, это название вызванного модуля.
frame:newChild
frame:newChild{ title = title, args = table }
- Note the use of named arguments.
Create a new Frame object that is a child of the current frame, with optional arguments and title.
This is mainly intended for use in the debug console for testing functions that would normally be called by {{#invoke:}}
. The number of frames that may be created at any one time is limited.
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.
If you are expanding a single parser function, use frame:callParserFunction
for the same reasons.
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 }
- Note the use of named arguments.
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 compatibility.
Библиотека Hash
mw.hash.hashValue
mw.hash.hashValue( algo, value )
Hashes a string value with the specified algorithm. Valid algorithms may be fetched using mw.hash.listAlgorithms().
mw.hash.listAlgorithms
mw.hash.listAlgorithms()
Returns a list of supported hashing algorithms, for use in mw.hash.hashValue().
Библиотека HTML
mw.html
- это удобный интерфейс для создания сложного HTML на Lua. Объект mw.html можно создать с помощью mw.html.create
.
Functions documented as mw.html.name
are available on the global mw.html
table; functions documented as mw.html:name
and html:name
are methods of an mw.html object (see mw.html.create
).
Базовый пример может выглядеть так:
local div = mw.html.create( 'div' )
div
:attr( 'id', 'testdiv' )
:css( 'width', '100%' )
:wikitext( 'Some text' )
:tag( 'hr' )
return tostring( div )
-- Output: <div id="testdiv" style="width:100%;">Some text<hr /></div>
mw.html.create
mw.html.create( tagName, args )
Создает новый объект mw.html, содержащий html-элемент tagName
. Вы также можете передать пустую строку или nil как tagName
для создания пустого объект mw.html.
args
может быть таблица со следующими ключами:
args.selfClosing
: заставляет текущий тег самозакрываться, даже если mw.html не распознает его как самозакрывающийсяargs.parent
: родитель текущего экземпляра mw.html (предназначен для внутреннего использования)
mw.html:node
html:node( builder )
Добавляет дочерний узел mw.html (builder
) к текущему экземпляру mw.html. Если передан параметр nil, это не работает. Узел (builder
) - это строковое представление элемента html.
mw.html:wikitext
html:wikitext( ... )
Добавляет неопределенное количество строк викитекста к объекту mw.html.
Обратите внимание, что это останавливается на первом элементе nil.
mw.html:newline
html:newline()
Добавляет новую строку к объекту mw.html.
mw.html:tag
html:tag( tagName, args )
Добавляет новый дочерний узел с заданным tagName
к построителю и возвращает экземпляр mw.html, представляющий этот новый узел. Параметр args
идентичен параметру mw.html.create
Note that contrarily to other methods such as html:node()
, this method doesn't return the current mw.html instance, but the mw.html instance of the newly inserted tag.
Make sure to use html:done()
to go up to the parent mw.html instance, or html:allDone()
if you have nested tags on several levels.
mw.html:attr
html:attr( name, value )
html:attr( table )
Устанавливает атрибут HTML с заданными name
и value
узла. В качестве альтернативы можно передать таблицу, содержащую пары атрибутов имя->значение, которые нужно установить. В первой способе установки значение nil приводит к сбросу любого атрибута с заданным именем, если он был установлен ранее.
mw.html:getAttr
html:getAttr( name )
Получить значение атрибута html, ранее установленное с помощью html:attr()
с данным name
.
mw.html:addClass
html:addClass( class )
Добавляет имя класса к атрибуту класса узла. Если передан параметр nil, это не работает.
mw.html:css
html:css( name, value )
html:css( table )
Задаёт свойство CSS с заданными name
и value
узла. В качестве альтернативы можно передать таблицу, содержащую пары свойств name->value, которые требуется установить. В первом способе значение nil приводит к сбросу любого свойства с заданным именем, если оно было установлено ранее.
mw.html:cssText
html:cssText( css )
Добавьте строку css
к атрибуту стиля узла. Если передан параметр nil, это не работает.
mw.html:done
html:done()
Возвращает родительский узел, под которым был создан текущий узел. Подобно jQuery.end, это удобная функция, позволяющая объединить несколько дочерних узлов в один оператор.
mw.html:allDone
html:allDone()
Like html:done()
, but traverses all the way to the root node of the tree and returns it.
Библиотека Language
Language codes are described at language code. Many of MediaWiki's language codes are similar to IETF language tags, but not all MediaWiki language codes are valid IETF tags or vice versa.
Functions documented as mw.language.name
are available on the global mw.language
table; functions documented as mw.language:name
and lang:name
are methods of a language object (see mw.language.new
or mw.language.getContentLanguage
).
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.fetchLanguageNames
mw.language.fetchLanguageNames()
mw.language.fetchLanguageNames( inLanguage )
mw.language.fetchLanguageNames( inLanguage, include )
Fetch the list of languages known to MediaWiki, returning a table mapping language code to language name.
By default the name returned is the language autonym; passing a language code for inLanguage
returns all names in that language.
By default, only language names known to MediaWiki are returned; passing 'all'
for include
will return all available languages (e.g. from Расширение:CLDR ), while passing 'mwfile'
will include only languages having customized messages included with MediaWiki core or enabled extensions. To explicitly select the default, 'mw'
may be passed.
mw.language.getContentLanguage
mw.language.getContentLanguage()
mw.getContentLanguage()
Returns a new language object for the wiki's default content language.
mw.language.getFallbacksFor

mw.language.getFallbacksFor( code )
Returns a list of MediaWiki's fallback language codes for the specified code.
mw.language.isKnownLanguageTag
mw.language.isKnownLanguageTag( code )
Returns true if a language code is known to MediaWiki.
A language code is "known" if it is a "valid built-in code" (i.e. it returns true for mw.language.isValidBuiltInCode
) and returns a non-empty string for mw.language.fetchLanguageName
.
mw.language.isSupportedLanguage
mw.language.isSupportedLanguage( code )
Checks whether any localisation is available for that language code in MediaWiki.
A language code is "supported" if it is a "valid" code (returns true for mw.language.isValidCode
), contains no uppercase letters, and has a message file in the currently-running version of MediaWiki.
It is possible for a language code to be "supported" but not "known" (i.e. returning true for mw.language.isKnownLanguageTag
). Also note that certain codes are "supported" despite mw.language.isValidBuiltInCode
returning false.
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.
A language code is a "valid built-in code" if it is a "valid" code (i.e. it returns true for mw.language.isValidCode
); consists of only ASCII letters, numbers, and hyphens; and is at least two characters long.
Note that some codes are "supported" (i.e. returning true from mw.language.isSupportedLanguage
) even though this function returns false.
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.
A language code is valid if it does not contain certain unsafe characters (colons, single- or double-quotes, slashs, backslashs, angle brackets, ampersands, or ASCII NULs) and is otherwise allowed in a page title.
mw.language.new
mw.language.new( code )
mw.getLanguage( code )
Creates a new language object. Language objects do not have any publicly accessible properties, but they do have several methods, which are documented below.
There is a limit on the number of distinct language codes that may be used on a page. Exceeding this limit will result in errors.
mw.language:getCode
lang:getCode()
Returns the language code for this language object.
mw.language:getFallbackLanguages
lang:getFallbackLanguages()
Returns a list of MediaWiki's fallback language codes for this language object. Equivalent to mw.language.getFallbacksFor( lang:getCode() )
.
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 )
lang:formatNum( n, options )
Formats a number with grouping and decimal separators appropriate for the given language. Given 123456.78, this may produce "123,456.78", "123.456,78", or even something like "١٢٣٬٤٥٦٫٧٨" depending on the language and wiki configuration.
The options
is a table of options, which can be:
noCommafy
: Set true to omit grouping separators and use a dot (.
) as the decimal separator.
Digit transformation may still occur, which may include transforming the decimal separator.
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 value for local
must be a boolean or nil; if true, the time is formatted in the wiki'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 Расширение:ParserFunctions .
Note however that backslashes may need to be doubled in a Lua string literal, since Lua also uses backslash as an escape character while wikitext does not:
-- This string literal contains a newline, not the two characters "\n", so it is not equivalent to {{#time:\n}}.
lang:formatDate( '\n' )
-- This is equivalent to {{#time:\n}}, not {{#time:\\n}}.
lang:formatDate( '\\n' )
-- This is equivalent to {{#time:\\n}}, not {{#time:\\\\n}}.
lang:formatDate( '\\\\n' )
mw.language:formatDuration
lang:formatDuration( seconds )
lang:formatDuration( seconds, chosenIntervals )
Breaks a duration in seconds into more human-readable units, e.g. 12345 to 3 hours, 25 minutes and 45 seconds, returning the result as a string.
chosenIntervals
, if given, is a table with values naming the interval units to use in the response. These include 'millennia
', 'centuries
', 'decades
', 'years
', 'weeks
', 'days
', 'hours
', 'minutes
', and 'seconds
'.
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 localization of magic words and translatewiki's FAQ on 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, whilegrammar
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 Special:MyLanguage/Help:Magic words#Localisation 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.
mw.language:getArrow
lang:getArrow( direction )
Returns a Unicode arrow character corresponding to direction
:
- forwards: Either "→" or "←" depending on the directionality of the language.
- backwards: Either "←" or "→" depending on the directionality of the language.
- left: "←"
- right: "→"
- up: "↑"
- down: "↓"
mw.language:getDir
lang:getDir()
Returns "ltr" or "rtl", depending on the directionality of the language.
mw.language:getDirMark
lang:getDirMark( opposite )
Returns a string containing either U+200E (the left-to-right mark) or U+200F (the right-to-left mark), depending on the directionality of the language and whether opposite
is a true or false value.
mw.language:getDirMarkEntity
lang:getDirMarkEntity( opposite )
Returns "‎" or "‏", depending on the directionality of the language and whether opposite
is a true or false value.
mw.language:getDurationIntervals
lang:getDurationIntervals( seconds )
lang:getDurationIntervals( seconds, chosenIntervals )
Breaks a duration in seconds into more human-readable units, e.g. 12345 to 3 hours, 25 minutes and 45 seconds, returning the result as a table mapping unit names to numbers.
chosenIntervals
, if given, is a table with values naming the interval units to use in the response. These include 'millennia
', 'centuries
', 'decades
', 'years
', 'weeks
', 'days
', 'hours
', 'minutes
', and 'seconds
'.
Those unit keywords are also the keys used in the response table. Only units with a non-zero value are set in the response, unless the response would be empty in which case the smallest unit is returned with a value of 0.
Message library
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
and msg: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 remaining parameters are passed to the new object's params()
method.
The message object has no properties, 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 properties, 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 properties, 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()
Returns a Language object for the default language.
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(). If a sequence table is used, parameters must be directly present in the table; references using the __index metamethod will not work.
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:plain
msg:plain()
Substitutes the parameters and returns the message wikitext as-is. Template calls and parser functions are intact.
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 exist or if the message is the empty string or the string "-".
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.
- 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
has the special value "*
", the result is 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 ("all", "subcats", "files", "pages"), the result is a number with the corresponding value.
Each new category queried will increment the expensive function count.
mw.site.stats.pagesInNamespace
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.
mw.site.interwikiMap
mw.site.interwikiMap( filter )
Returns a table holding data about available interwiki prefixes. If filter
is the string "local", then only data for local interwiki prefixes is returned. If filter
is the string "!local", then only data for non-local prefixes is returned. If no filter is specified, data for all prefixes is returned. A "local" prefix in this context is one that is for the same project. For example, on the English Wikipedia, other-language Wikipedias are considered local, while Wiktionary and such are not.
Keys in the table returned by this function are interwiki prefixes, and the values are subtables with the following properties:
- prefix - the interwiki prefix.
- url - the URL that the interwiki points to. The page name is represented by the parameter $1.
- isProtocolRelative - a boolean showing whether the URL is protocol-relative.
- isLocal - whether the URL is for a site in the current project.
- isCurrentWiki - whether the URL is for the current wiki.
- isTranscludable - whether pages using this interwiki prefix are transcludable. This requires scary transclusion, which is disabled on Wikimedia wikis.
- isExtraLanguageLink - whether the interwiki is listed in
$wgExtraInterlanguageLinkPrefixes
.
- displayText - for links listed in $wgExtraInterlanguageLinkPrefixes, this is the display text shown for the interlanguage link. Nil if not specified.
- tooltip - for links listed in $wgExtraInterlanguageLinkPrefixes, this is the tooltip text shown when users hover over the interlanguage link. Nil if not specified.
Text library
The text library provides some common text processing functions missing from the String library and the Ustring library. These functions are safe for use with UTF-8 strings.
mw.text.decode
mw.text.decode( s )
mw.text.decode( s, decodeNamedEntities )
Replaces HTML entities in the string with the corresponding characters.
If boolean decodeNamedEntities
is omitted or false, the only named entities recognized are <
(<), >
(>), &
(&), "
(") and
(the non-breaking space, U+00A0).
Otherwise, the list of HTML5 named entities to recognize is loaded from PHP's get_html_translation_table
function.
Known bugs: Approximately 600 of around 2200 named entities in the HTML5 standard do not get decoded, even when decodeNamedEntities
is used; this includes approximately 40 of around 250 entities which are also included in HTML4.
This occurs because PHP's get_html_translation_table
function returns only one mapping for each character, so for example
is not decoded since PHP returns only →
as the mapping for →
.
→
mw.text.encode
mw.text.encode( s )
mw.text.encode( s, charset )
Replaces characters in a string with HTML entities.
Five characters are replaced with the appropriate named entities: <
, >
, &
, "
and the non-breaking space (U+00A0).
All others are replaced with numeric entities.
If charset
is supplied, it should be a string as appropriate to go inside brackets in a Ustring pattern, i.e. the "set" in [set]
. The default charset contains six characters: <
, >
, &
, "
, '
and the non-breaking space (U+00A0).
mw.text.jsonDecode
mw.text.jsonDecode( s )
mw.text.jsonDecode( s, flags )
Decodes a JSON string. flags
is 0 or a combination (use +
) of the flags mw.text.JSON_PRESERVE_KEYS
and mw.text.JSON_TRY_FIXING
.
Normally JSON's zero-based arrays are renumbered to Lua one-based sequence tables; to prevent this, pass mw.text.JSON_PRESERVE_KEYS
.
To relax certain requirements in JSON, such as no terminal comma in arrays or objects, pass mw.text.JSON_TRY_FIXING
. This is not recommended.
Limitations:
- Decoded JSON arrays may not be Lua sequences if the array contains null values.
- JSON objects will drop keys having null values.
- It is not possible to directly tell whether the input was a JSON array or a JSON object with sequential integer keys.
- A JSON object having sequential integer keys beginning with 1 will decode to the same table structure as a JSON array with the same values, despite these not being at all equivalent, unless
mw.text.JSON_PRESERVE_KEYS
is used.
mw.text.jsonEncode
mw.text.jsonEncode( value )
mw.text.jsonEncode( value, flags )
Encode a JSON string. Errors are raised if the passed value cannot be encoded in JSON. flags
is 0 or a combination (use +
) of the flags mw.text.JSON_PRESERVE_KEYS
and mw.text.JSON_PRETTY
.
Normally Lua one-based sequence tables are encoded as JSON zero-based arrays; when mw.text.JSON_PRESERVE_KEYS
is set in flags
, zero-based sequence tables are encoded as JSON arrays.
Limitations:
- Empty tables are always encoded as empty arrays (
[]
), not empty objects ({}
). - Sequence tables cannot be encoded as JSON objects without adding a "dummy" element.
- To produce objects or arrays with nil values, a tricky implementation of the
__pairs
metamethod is required. - A Lua table having sequential integer keys beginning with 0 will encode as a JSON array, the same as a Lua table having integer keys beginning with 1, unless
mw.text.JSON_PRESERVE_KEYS
is used. - When both a number and the string representation of that number are used as keys in the same table, behavior is unspecified.
mw.text.killMarkers
mw.text.killMarkers( s )
Removes all MediaWiki strip markers from a string.
mw.text.listToText
mw.text.listToText( list )
mw.text.listToText( list, separator, conjunction )
Joins a list, prose-style. In other words, it's like table.concat()
but with a different separator before the final item.
The default separator is taken from MediaWiki:comma-separator in the wiki's content language, and the default conjunction is MediaWiki:and concatenated with MediaWiki:word-separator.
Examples, using the default values for the messages:
-- Returns the empty string
mw.text.listToText( {} )
-- Returns "1"
mw.text.listToText( { 1 } )
-- Returns "1 and 2"
mw.text.listToText( { 1, 2 } )
-- Returns "1, 2, 3, 4 and 5"
mw.text.listToText( { 1, 2, 3, 4, 5 } )
-- Returns "1; 2; 3; 4 or 5"
mw.text.listToText( { 1, 2, 3, 4, 5 }, '; ', ' or ' )
mw.text.nowiki
mw.text.nowiki( s )
Replaces various characters in the string with HTML entities to prevent their interpretation as wikitext. This includes:
- The following characters:
"
,&
,'
,<
,=
,>
,[
,]
,{
,|
,}
- The following characters at the start of the string or immediately after a newline:
#
,*
,:
,;
, space, tab (\t
) - Blank lines will have one of the associated newline or carriage return characters escaped
----
at the start of the string or immediately after a newline will have the first-
escaped__
will have one underscore escaped://
will have the colon escaped- A whitespace character following
ISBN
,RFC
, orPMID
will be escaped
mw.text.split
mw.text.split( s, pattern, plain )
Splits the string into substrings at boundaries matching the Ustring pattern pattern
. If plain
is specified and true, pattern
will be interpreted as a literal string rather than as a Lua pattern (just as with the parameter of the same name for mw.ustring.find()
). Returns a table containing the substrings.
For example, mw.text.split( 'a b\tc\nd', '%s' )
would return a table { 'a', 'b', 'c', 'd' }
.
If pattern
matches the empty string, s
will be split into individual characters.
mw.text.gsplit
mw.text.gsplit( s, pattern, plain )
Returns an iterator function that will iterate over the substrings that would be returned by the equivalent call to mw.text.split()
.
mw.text.tag
mw.text.tag( name, attrs, content )
mw.text.tag{ name = string, attrs = table, content = string|false }
- Note the use of named arguments.
Generates an HTML-style tag for name
.
If attrs
is given, it must be a table with string keys. String and number values are used as the value of the attribute; boolean true results in the key being output as an HTML5 valueless parameter; boolean false skips the key entirely; and anything else is an error.
If content
is not given (or is nil), only the opening tag is returned. If content
is boolean false, a self-closed tag is returned. Otherwise it must be a string or number, in which case that content is enclosed in the constructed opening and closing tag. Note the content is not automatically HTML-encoded; use mw.text.encode() if needed.
For properly returning extension tags such as <ref>
, use frame:extensionTag() instead.
mw.text.trim
mw.text.trim( s )
mw.text.trim( s, charset )
Remove whitespace or other characters from the beginning and end of a string.
If charset
is supplied, it should be a string as appropriate to go inside brackets in a Ustring pattern, i.e. the "set" in [set]
. The default charset is ASCII whitespace, %s
, which is equivalent to "\t\r\n\f\v "
.
mw.text.truncate
mw.text.truncate( text, length )
mw.text.truncate( text, length, ellipsis )
mw.text.truncate( text, length, ellipsis, adjustLength )
Truncates text
to the specified length in code points, adding ellipsis
if truncation was performed. If length is positive, the end of the string will be truncated; if negative, the beginning will be removed. If adjustLength
is given and true, the resulting string including ellipsis will not be longer than the specified length.
The default value for ellipsis
is taken from MediaWiki:ellipsis in the wiki's content language.
Examples, using the default "..." ellipsis:
-- Returns "foobarbaz"
mw.text.truncate( "foobarbaz", 9 )
-- Returns "fooba..."
mw.text.truncate( "foobarbaz", 5 )
-- Returns "...arbaz"
mw.text.truncate( "foobarbaz", -5 )
-- Returns "foo..."
mw.text.truncate( "foobarbaz", 6, nil, true )
-- Returns "foobarbaz", because that's shorter than "foobarba..."
mw.text.truncate( "foobarbaz", 8 )
mw.text.unstripNoWiki
mw.text.unstripNoWiki( s )
Replaces MediaWiki <nowiki> strip markers with the corresponding text. Other types of strip markers are not changed.
mw.text.unstrip
mw.text.unstrip( s )
Equivalent to mw.text.killMarkers( mw.text.unstripNoWiki( s ) )
.
This no longer reveals the HTML behind special page transclusion, <ref> tags, and so on as it did in earlier versions of Scribunto.
Title library
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
.
This compares titles by interwiki prefix (if any) as strings, then by namespace number, then by the unprefixed title text as a string. These string comparisons use Lua's standard <
operator.
mw.title.getCurrentTitle
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 when called with an ID
Creates a new title object.
If a number id
is given, an object is created for the title with that page_id. The title referenced will be counted as linked from the current page. If the page_id does not exist, returns nil. The expensive function count will be incremented if the title object created is not for a title that has already been loaded.
If a 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 )
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.
Note that, unlike mw.title.new()
, this method will always apply the specified namespace. For example, mw.title.makeTitle( 'Template', 'Module:Foo' )
will create an object for the page Template:Module:Foo, while mw.title.new( 'Module:Foo', 'Template' )
will create an object for the page Module:Foo.
Note also that functionality for interwiki titles is limited to interwiki
/ isExternal
/ isLocal
and URL-related methods; other methods might not behave as expected.
Title objects
A title object has a number of properties and methods. Most of the properties are read-only.
Note that fields ending with text
return titles as string values whereas the fields ending with title
return title objects.
- id: The page_id.
0
if the page does not exist.
This may be expensive.
- interwiki: The interwiki prefix, or the empty string if none.
- namespace: The namespace number.
- fragment: The fragment (aka section/anchor linking), 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. Interwiki is not returned if equal to the current.
- 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. Alias for
file.exists
for Media-namespace titles. For File-namespace titles this checks the existence of the file description page, not the file itself. This may be expensive.
- file, fileExists: See #File metadata below.
- 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. This may be expensive.
- 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. This may be expensive.
- 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 )
, ornil
if this title cannot have a talk page.
- subjectPageTitle: The same as
mw.title.makeTitle( mw.site.namespaces[title.namespace].subject.id, title.text )
.
- redirectTarget: Returns a title object of the target of the redirect page if the page is a redirect and the page exists, returns
false
otherwise.
- protectionLevels: The page's protection levels. This is a table with keys corresponding to each action (e.g.,
"edit"
and"move"
). The table values are arrays, the first item of which is a string containing the protection level. If the page is unprotected, either the table values or the array items will benil
. This is expensive.
- cascadingProtection: The cascading protections applicable to the page. This is a table with keys
"restrictions"
(itself a table with keys likeprotectionLevels
has) and"sources"
(an array listing titles where the protections cascade from). If no protections cascade to the page,"restrictions"
and"sources"
will be empty. This is expensive.
- 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.
- getContent(): Returns the (unparsed) content of the page, or
nil
if there is no page. The page will be recorded as a transclusion.
Title objects may be compared using relational operators. tostring( title )
will return title.prefixedText
.
Since people find the fact surprising, note that accessing any expensive field on a title object records a "link" to the page (as shown on Special:WhatLinksHere, for example). Using the title object's getContent()
method or accessing the redirectTarget
field records it as a "включение", and accessing the title object's file
or fileExists
fields records it as a "ссылка на файл".
File metadata
Title objects representing a page in the File or Media namespace will have a property called file
. This is expensive. This is a table, structured as follows:
- exists: Whether the file exists. It will be recorded as an image usage. The
fileExists
property on a Title object exists for backwards compatibility reasons and is an alias for this property. If this isfalse
, all other file properties will benil
.
- width: The width of the file. If the file contains multiple pages, this is the width of the first page.
- height: The height of the file. If the file contains multiple pages, this is the height of the first page.
- pages: If the file format supports multiple pages, this is a table containing tables for each page of the file; otherwise, it is
nil
. The # operator can be used to get the number of pages in the file. Each individual page table contains a width and height property.
- size: The size of the file in bytes.
- mimeType: The MIME type of the file.
- length: The length (duration) of the media file in seconds. Zero for media types which do not support length.
Expensive properties
The properties id
, isRedirect
, exists
, and contentModel
require fetching data about the title from the database. For this reason, the expensive function count is incremented the first time one of them is accessed for a page other than the current page. Subsequent accesses of any of these properties for that page will not increment the expensive function count again.
Other properties marked as expensive will always increment the expensive function count the first time they are accessed for a page other than the current page.
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 reversible, 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, i, j )
Decodes the query string s
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.
The optional numerical arguments i
and j
can be used to specify a substring of s
to be parsed, rather than the entire string. i
is the position of the first character of the substring, and defaults to 1. j
is the position of the last character of the substring, and defaults to the length of the string. Both i
and j
can be negative, as in string.sub.
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 length of a pattern, in bytes.
mw.ustring.maxStringLength
The maximum allowed length 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 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.
local value = mw.ustring.char( 0x41f, 0x440, 0x438, 0x432, 0x435, 0x442, 0x21 ) -- value is now 'Привет!'
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.
Known bugs: When used with a lone frontier pattern (%f[set]
), the function will get stuck in an infinite loop. For example, the following loop never terminates:
for capture in mw.ustring.gmatch( "foo bar", "%f[%w]" ) do
-- block
end
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.
Known bugs: When repl
is a table, it is possible to use numbers as keys instead of strings (e.g. to replace instances of
in a string, the value at key "5"
or [5]
would be used); as such, the output is not predictable if they have different (non-nil) values.
["5"]
This is not an issue for string.gsub(), which ignores any numbers as keys.
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.
See string.len() for a similar function that uses byte length rather than codepoints.
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 (also known as Normalization Form Canonical Composition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFD
mw.ustring.toNFD( s )
Converts the string to Normalization Form D (also known as Normalization Form Canonical Decomposition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFKC
mw.ustring.toNFKC( s )
Converts the string to Normalization Form KC (also known as Normalization Form Compatibility Composition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFKD
mw.ustring.toNFKD( s )
Converts the string to Normalization Form KD (also known as Normalization Form Compatibility Decomposition). 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 "Number, decimal digit".
%l
: represents all characters with General Category "Lowercase Letter".
%p
: represents all characters with General Category "Punctuation".
%s
: represents all characters with General Category "Separator", plus tab, linefeed, carriage return, vertical tab, and form feed.
%u
: represents all characters with General Category "Uppercase Letter".
%w
: represents all characters with General Category "Letter" or "Decimal Number".
%x
: adds fullwidth character versions of the hex digits.
Like in String library patterns, %A
, %C
, %D
, %L
, %P
, %S
, %U
и %W
here represent the complementary set ("all characters without given General Category").
In all cases, characters are interpreted as Unicode characters instead of bytes, so ranges such as [0-9]
, patterns such as %b«»
, and quantifiers applied to multibyte characters will work correctly. Empty captures will capture the position in code points rather than bytes.
Known limitations: Unlike String library patterns, Ustring library patterns have a maximum length of 10,000 bytes. If the pattern exceeds this length, then the Ustring function will throw an error. Because the String library has its own maximum of 32 captures (unlike the Ustring library), it is therefore impossible to use a pattern which exceeds both limits, as it will be incompatible with both libraries.
Note: 9 ASCII characters, $
, +
, <
, =
, >
, ^
, `
, |
, ~
, can be matched by %p
in the string library but not in the ustring library, as Unicode classifies them as Symbols rather than Punctuation.
Loadable libraries
These libraries are not included by default, but if needed may be loaded using require()
.
bit32
This emulation of the Lua 5.2 bit32
library may be loaded using:
bit32 = require( 'bit32' )
The bit32 library provides bitwise operations on unsigned 32-bit integers. Input numbers are truncated to integers (in an unspecified manner) and reduced modulo 232 so the value is in the range 0 to 232−1; return values are also in this range.
When bits are numbered (as in bit32.extract()), 0 is the least-significant bit (the one with value 20) and 31 is the most-significant (the one with value 231).
bit32.band
bit32.band( ... )
Returns the bitwise AND of its arguments: the result has a bit set only if that bit is set in all of the arguments.
If given zero arguments, the result has all bits set.
bit32.bnot
bit32.bnot( x )
Returns the bitwise complement of x
.
bit32.bor
bit32.bor( ... )
Returns the bitwise OR of its arguments: the result has a bit set if that bit is set in any of the arguments.
If given zero arguments, the result has all bits clear.
bit32.btest
bit32.btest( ... )
Equivalent to bit32.band( ... ) ~= 0
bit32.bxor
bit32.bxor( ... )
Returns the bitwise XOR of its arguments: the result has a bit set if that bit is set in an odd number of the arguments.
If given zero arguments, the result has all bits clear.
bit32.extract
bit32.extract( n, field, width )
Extracts width
bits from n
, starting with bit field
. Accessing bits outside of the range 0 to 31 is an error.
If not specified, the default for width
is 1.
bit32.replace
bit32.replace( n, v, field, width )
Replaces width
bits in n
, starting with bit field
, with the low width
bits from v
. Accessing bits outside of the range 0 to 31 is an error.
If not specified, the default for width
is 1.
bit32.lshift
bit32.lshift( n, disp )
Returns the number n
shifted disp
bits to the left. This is a logical shift: inserted bits are 0. This is generally equivalent to multiplying by 2disp
.
Note that a displacement over 31 will result in 0.
bit32.rshift
bit32.rshift( n, disp )
Returns the number n
shifted disp
bits to the right. This is a logical shift: inserted bits are 0. This is generally equivalent to dividing by 2disp
.
Note that a displacement over 31 will result in 0.
bit32.arshift
bit32.arshift( n, disp )
Returns the number n
shifted disp
bits to the right. This is an arithmetic shift: if disp
is positive, the inserted bits will be the same as bit 31 in the original number.
Note that a displacement over 31 will result in 0 or 4294967295.
bit32.lrotate
bit32.lrotate( n, disp )
Returns the number n
rotated disp
bits to the left.
Note that rotations are equivalent modulo 32: a rotation of 32 is the same as a rotation of 0, 33 is the same as 1, and so on.
bit32.rrotate
bit32.rrotate( n, disp )
Returns the number n
rotated disp
bits to the right.
Note that rotations are equivalent modulo 32: a rotation of 32 is the same as a rotation of 0, 33 is the same as 1, and so on.
libraryUtil
This library contains methods useful when implementing Scribunto libraries. It may be loaded using:
libraryUtil = require( 'libraryUtil' )
libraryUtil.checkType
libraryUtil.checkType( name, argIdx, arg, expectType, nilOk )
Raises an error if type( arg )
does not match expectType
. In addition, no error will be raised if arg
is nil and nilOk
is true.
name
is the name of the calling function, and argIdx
is the position of the argument in the argument list. These are used in formatting the error message.
libraryUtil.checkTypeMulti
libraryUtil.checkTypeMulti( name, argIdx, arg, expectTypes )
Raises an error if type( arg )
does not match any of the strings in the array expectTypes
.
This is for arguments that have more than one valid type.
libraryUtil.checkTypeForIndex
libraryUtil.checkTypeForIndex( index, value, expectType )
Raises an error if type( value )
does not match expectType
.
This is intended for use in implementing a __newindex
metamethod.
libraryUtil.checkTypeForNamedArg
libraryUtil.checkTypeForNamedArg( name, argName, arg, expectType, nilOk )
Raises an error if type( arg )
does not match expectType
. In addition, no error will be raised if arg
is nil and nilOk
is true.
This is intended to be used as an equivalent to libraryUtil.checkType()
in methods called using Lua's "named argument" syntax, func{ name = value }
.
libraryUtil.makeCheckSelfFunction
libraryUtil.makeCheckSelfFunction( libraryName, varName, selfObj, selfObjDesc )
This is intended for use in implementing "methods" on object tables that are intended to be called with the obj:method()
syntax. It returns a function that should be called at the top of these methods with the self
argument and the method name, which will raise an error if that self
object is not selfObj
.
This function will generally be used in a library's constructor function, something like this:
function myLibrary.new()
local obj = {}
local checkSelf = libraryUtil.makeCheckSelfFunction( 'myLibrary', 'obj', obj, 'myLibrary object' )
function obj:method()
checkSelf( self, 'method' )
end
function obj:method2()
checkSelf( self, 'method2' )
end
return obj
end
luabit
The luabit library modules "bit" and "hex" may be loaded using:
bit = require( 'luabit.bit' )
hex = require( 'luabit.hex' )
Note that the bit32 library contains the same operations as "luabit.bit", and the operations in "luabit.hex" may be performed using string.format()
and tonumber()
.
The luabit module "noki" is not available, as it is entirely useless in Scribunto. The luabit module "utf8" is also not available, as it was considered redundant to the Ustring library.
strict
The strict library is not a normal library; it causes an error to be raised whenever a new variable is used that is not explicitly scoped as a local variable (e.g., global variable assignment references). This functionality is typically enabled by loading at the top of a module using:
require( 'strict' )
On many Wikimedia wikis this was formerly implemented in Module:No globals
. It is in part derived from strict.lua.
ustring
The pure-Lua backend to the Ustring library may be loaded using:
ustring = require( 'ustring' )
In all cases the Ustring library (mw.ustring
) should be used instead, as that replaces many of the slower and more memory-intensive operations with callbacks into PHP code.
Extension libraries
Some MediaWiki extensions provide additional Scribunto libraries. These are also located in the table mw
, usually in the table mw.ext
, however, they are only present when certain extensions are installed (in addition to the Scribunto extension itself).
Such extensions use Scribunto provided hooks:
Writing Scribunto libraries provides information on how such libraries can be developed to provide Lua interfaces for MediaWiki extensions.
The following libraries are planned, or are in Gerrit pending review.
- (none at this time)
mw.wikibase
Расширение:Wikibase Client provides access to localizable structured data, most notably Wikidata. See docs_topics_lua.html and Extension:Wikibase Client/Lua .
mw.wikibase.lexeme
WikibaseLexeme provides access to Wikibase Lexeme entities. This is supported by Wikidata:Lexicographical data.
mw.wikibase.mediainfo
WikibaseMediaInfo provides access to Wikibase MediaInfo entities. See Extension:WikibaseMediaInfo/Lua . This is supported by Structured Data on Commons. See Commons:Structured data/Lua.
mw.bcmath
BCmath provides arbitrary-precision arithmetic to Lua modules. See BCmath documentation via "LDoc" link at Extension:BCmath#Usage.
mw.smw
Semantic Scribunto provides native support for the Scribunto extension to Semantic MediaWiki extension.
mw.ext.data
JsonConfig provides access to localizable tabular and map data. See Extension:JsonConfig/Tabular . Tabular Data and GeoJSON Map Data is supported in Commons "Data:" namespace.
mw.ext.data.get( pagename )
mw.ext.cargo
Cargo provides a means to query its data store from Lua. See Extension:Cargo/Other features#Lua support.
mw.ext.cattools
CategoryToolbox provides a means to check from Lua if a certain page belongs to a category. Is is experimental and not enabled on public WikiMedia wikis.
mw.ext.FlaggedRevs
FlaggedRevs provides a means to access the stability settings of a page from Lua.
mw.ext.TitleBlacklist
TitleBlacklist provides a means to test and obtain information about blacklisted page naming entries from Lua.
mw.ext.ParserFunctions
ParserFunctions provides a means from Lua to evaluate expressions in the same way as its PHP-based parser function #expr
.
mw.ext.proofreadPage
Proofread Page provides access to Index and Page namespaces. See Extension:Proofread Page/Lua reference . This is supported by Wikisource:ProofreadPage. See Help:Extension:ProofreadPage .
mw.ext.articlePlaceholder
ArticlePlaceholder provides a means to override default Wikibase renderings from Lua. See Extension:ArticlePlaceholder/Module:AboutTopic .
mw.ext.externalData
ExternalData provides a means to get structured data from Internet from Lua. See Extension:External Data/Lua .
mw.ext.UnlinkedWikibase.xxx
See UnlinkedWikibase
- mw.ext.UnlinkedWikibase.getEntity( id )
- mw.ext.UnlinkedWikibase.query( sparql )
mw.ext.seo
WikiSEO provides a means to set SEO Data for the current page. See Extension:WikiSEO#Usage in lua modules.
mw.slots.xxx
- mw.slots.slotContent(slotName, pageName)
- mw.slots.slotTemplates(slotName, pageName) (deprecated)
- mw.slots.slotContentModel(slotName, pageName)
- mw.slots.slotData(slotName, pageName)
Differences from standard Lua
Changed functions
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.
- pairs()
- ipairs()
- Support for the __pairs and __ipairs metamethods (added in Lua 5.2) has been added.
- 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.
Removed functions and packages
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.
Additional caveats
- Referential data structures
- Circular data structures and data structures where the same node may be reached by more than one path cannot be correctly sent to PHP.
Attempting to do so will cause undefined behavior. This includes (but is not limited to) returning such data structures from the module called by {{#invoke:}}
and passing such data structures as parameters to Scribunto library functions that are implemented as callbacks into PHP.
Such data structures may be used freely within Lua, including as the return values of modules loaded with mw.loadData()
.
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. Also, if the library is loaded with PHP, any upvalues that its Lua functions have will not be reset between #invoke's. Care must be taken to ensure that modules can't abuse this to transfer information between #invoke's.
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 testn
, and a string that is the expected output for testn
. - 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 an iterated for loop, and each iteration's return values are accumulated. - ToString: Like "Normal", except each return value is passed through
tostring()
.
Test cases in another extension
There are (at least) two ways to run PHPUnit tests:
- Run phpunit against core, allowing the tests/phpunit/suites/ExtensionsTestSuite.php to find the extension's tests using the UnitTestsList hook.
If your extension's test class names all contain a unique component (e.g. the extension's name), the --filter
option may be used to run only your extension's tests.
- Run phpunit against the extension directory, where it will pick up any file ending in "Test.php".
Either of these will work fine if Scribunto is loaded in LocalSettings.php. And it is easy for method #1 to work if Scribunto is not loaded, as the UnitTestsList hook can easily be written to avoid returning the Scribunto test when $wgAutoloadClasses[ 'Scribunto_LuaEngineTestBase' ]
is not set.
But Jenkins uses method #2. For Jenkins to properly run the tests, you will need to add Scribunto as a dependency for your extension. See Gerrit change 56570 for an example of how this is done.
If for some reason you need the tests to be able to run using method #2 without Scribunto loaded, one workaround is to add this check to the top of your unit test file:
if ( !isset( $GLOBALS['wgAutoloadClasses']['Scribunto_LuaEngineTestBase'] ) ) {
return;
}
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 the Extension libraries subsection above.
См. также
License
This manual is derived from the Lua 5.1 reference manual, which is available under the MIT 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.