添加的内容 删除的内容
无编辑摘要 |
小 (文本替换 - 替换“的的”为“的”) |
||
(未显示2个用户的5个中间版本) | |||
第34行: | 第34行: | ||
从模板的环境中调用Lua代码确实是一个好办法。 |
从模板的环境中调用Lua代码确实是一个好办法。 |
||
这意味着从调用页面的角度来说,语法不依赖与模板逻辑是否被Lua或者 |
这意味着从调用页面的角度来说,语法不依赖与模板逻辑是否被Lua或者wikitext执行。 |
||
这也避免了把复杂语法加到wiki内容命名空间中。 |
这也避免了把复杂语法加到wiki内容命名空间中。 |
||
第44行: | 第44行: | ||
对于模块来说,最好将所有的函数和变量声明为局部变量。 |
对于模块来说,最好将所有的函数和变量声明为局部变量。 |
||
=== 访问 |
=== 访问wikitext中的参数 === |
||
<code><nowiki>{{#invoke:}}</nowiki></code>调用函数时,会将[[#frame-object|框架对象(frame object)]]作为单一的参数。要访问传递到<code><nowiki>{{#invoke:}}</nowiki></code>的参数,代码通常会使用框架对象的<code>[[#frame.args|args]]</code>表,也可以访问传递到了包含<code><nowiki>{{#invoke:}}</nowiki></code>的模板的参数,方法是使用<code>[[#frame:getParent|frame:getParent()]]</code>,并访问该框架的<code>args</code>。 |
<code><nowiki>{{#invoke:}}</nowiki></code>调用函数时,会将[[#frame-object|框架对象(frame object)]]作为单一的参数。要访问传递到<code><nowiki>{{#invoke:}}</nowiki></code>的参数,代码通常会使用框架对象的<code>[[#frame.args|args]]</code>表,也可以访问传递到了包含<code><nowiki>{{#invoke:}}</nowiki></code>的模板的参数,方法是使用<code>[[#frame:getParent|frame:getParent()]]</code>,并访问该框架的<code>args</code>。 |
||
框架对象也用来访问对应环境的 |
框架对象也用来访问对应环境的wikitext解析器,例如[[#frame:callParserFunction|调用解析器函数]]、[[#frame:expandTemplate|扩展模板]]以及[[#frame:preprocess|展开任意的wikitext字符串]]。 |
||
=== 返回文本 === |
=== 返回文本 === |
||
模块函数通常返回单个的字符串;无论返回什么值都会通过[[#tostring|tostring()]]转换,然后连接在一起。这个字符串就是转化成 |
模块函数通常返回单个的字符串;无论返回什么值都会通过[[#tostring|tostring()]]转换,然后连接在一起。这个字符串就是转化成wikitext代码<code><nowiki>{{#invoke:}}</nowiki></code>的结果。 |
||
在解析页面的这一点上,模板都是已经被展开的,解析器函数和扩展标签都已经被处理,而且预存的转换(例如签名的扩展以及[[Help:链接#管道技巧|管道技巧]])都已经完成。因此,模块不能在输出文本中使用这些特性。例如,如果一个模块返回<code><nowiki>"Hello, world! {{welcome}}"</nowiki></code>,页面就会显示“Hello, world! <nowiki>{{welcome}}</nowiki>”。 |
在解析页面的这一点上,模板都是已经被展开的,解析器函数和扩展标签都已经被处理,而且预存的转换(例如签名的扩展以及[[Help:链接#管道技巧|管道技巧]])都已经完成。因此,模块不能在输出文本中使用这些特性。例如,如果一个模块返回<code><nowiki>"Hello, world! {{welcome}}"</nowiki></code>,页面就会显示“Hello, world! <nowiki>{{welcome}}</nowiki>”。 |
||
另一方面,替换引用是在加工的早期阶段处理的,所以只有当其他尝试的替换引用会被处理时才使用<code><nowiki>{{subst:#invoke:}}</nowiki></code>。失败的替换引用因为会保持为 |
另一方面,替换引用是在加工的早期阶段处理的,所以只有当其他尝试的替换引用会被处理时才使用<code><nowiki>{{subst:#invoke:}}</nowiki></code>。失败的替换引用因为会保持为wikitext,所以都会在'''下一次'''编辑时被处理。这通常需要避免。 |
||
=== 模块文档 === |
=== 模块文档 === |
||
Scruibunto允许模块可以被自动关联的模块 |
Scruibunto允许模块可以被自动关联的模块wikitext页面关联文档;默认情况下,模块的“/doc”子页面是用来作为文档,并且会在模块页面的代码顶部显示其内容。例如,“模块:Bananas”的文档页面就是“模块:Bananas/doc”。 |
||
这也可以使用以下MediaWiki命名空间下的消息配置: |
这也可以使用以下MediaWiki命名空间下的消息配置: |
||
* <code>scribunto-doc-page-name</code> —设置用来作文档页面的名称。 模块(除了模块:prefix)的名称会通过<code>$1</code>。 如果在模块命名空间,这里的页面通常会视为 |
* <code>scribunto-doc-page-name</code> —设置用来作文档页面的名称。 模块(除了模块:prefix)的名称会通过<code>$1</code>。 如果在模块命名空间,这里的页面通常会视为wikitext而不是Lua代码,也不会被<code><nowiki>{{#invoke:}}</nowiki></code>使用。 模块的页面通常是“Module:$1/doc”这样的模块/doc子页面。注意解析器函数等其他可扩展代码在这个消息中不被使用。 请注意,此消息中解析器函数和其他大括号扩展可能无法使用。 |
||
* <code>scribunto-doc-page-does-not-exist</code> — 文档页面不存在时显示的消息。 页面名称传递为<code>$1</code>。 默认为空。 |
* <code>scribunto-doc-page-does-not-exist</code> — 文档页面不存在时显示的消息。 页面名称传递为<code>$1</code>。 默认为空。 |
||
* <code>scribunto-doc-page-show</code> — 文档页面存在时显示的消息。 页面名称传递为<code>$1</code>。 默认是嵌入包含文档页面。 |
* <code>scribunto-doc-page-show</code> — 文档页面存在时显示的消息。 页面名称传递为<code>$1</code>。 默认是嵌入包含文档页面。 |
||
* <code>scribunto-doc-page-header</code> — 查看文档页面本身时显示的标题。 模块的名称(有Module:前缀)传递为<code>$1</code>。 默认以斜体显示简要说明。 |
* <code>scribunto-doc-page-header</code> — 查看文档页面本身时显示的标题。 模块的名称(有Module:前缀)传递为<code>$1</code>。 默认以斜体显示简要说明。 |
||
注意模块不可以被直接分类,也不可以直接添加跨 |
注意模块不可以被直接分类,也不可以直接添加跨站链接。这些应该放在文档页面里面的{{tag|includeonly}}标签中,当文档页面被引用到模块页面时,这些分类和跨站链接就会应用于模块页面。 |
||
这些应该放在文档页面里面的{{tag|includeonly}}标签中,当文档页面被引用到模块页面时,这些分类和跨维基链接就会应用于模块页面。 |
|||
== Lua语言 == |
== Lua语言 == |
||
第223行: | 第222行: | ||
==== 数字(number) ==== |
==== 数字(number) ==== |
||
Lua只有一种数字类型,就是典型的[[ |
Lua只有一种数字类型,就是典型的[[双精度浮点数]]。这种格式下,-9007199254740992到9007199254740992之间的整数都会准确表达,更大的数和带有小数部分的数将会受到舍入的误差。 |
||
数字可以用点(<code>.</code>)来表示小数,例如<code>123456.78</code>。数字也可以用不带空格的[[ |
数字可以用点(<code>.</code>)来表示小数,例如<code>123456.78</code>。数字也可以用不带空格的[[科学计数法]],例如<code>1.23e-10</code>、<code>123.45e20</code>或者<code>1.23E5</code>。也可以用16进制表示整数,方法就是以<code>0x</code>开头,例如<code>0x3A</code>。 |
||
虽然[[ |
虽然[[NaN]]和正负无穷大都可以正确地储存、处理,但是Lua不提供相应的直接文字表示方法。<code>math.huge</code>是正无穷大,相当于<code>1/0</code>,此外,像<code>0/0</code>这样的除法就可以生成NaN。 |
||
重申一遍,在转化为布尔值时,任何数字都会被视为true。这不像其他语言,数字0通常视为false。数字在转化为字符串时,数字都会被视为有限小数和科学计数;NaN是<syntaxhighlight lang="lua" inline>"nan"</syntaxhighlight>或者<syntaxhighlight lang="lua" inline>"-nan"</syntaxhighlight>;无穷大就是<syntaxhighlight lang="lua" inline>"inf"</syntaxhighlight>或<syntaxhighlight lang="lua" inline>"-inf"</syntaxhighlight>。 |
重申一遍,在转化为布尔值时,任何数字都会被视为true。这不像其他语言,数字0通常视为false。数字在转化为字符串时,数字都会被视为有限小数和科学计数;NaN是<syntaxhighlight lang="lua" inline>"nan"</syntaxhighlight>或者<syntaxhighlight lang="lua" inline>"-nan"</syntaxhighlight>;无穷大就是<syntaxhighlight lang="lua" inline>"inf"</syntaxhighlight>或<syntaxhighlight lang="lua" inline>"-inf"</syntaxhighlight>。 |
||
第287行: | 第286行: | ||
Lua中的函数是一等的(first-class)的值:可以匿名创建,或作为参数传递,或给变量赋值,等等。 |
Lua中的函数是一等的(first-class)的值:可以匿名创建,或作为参数传递,或给变量赋值,等等。 |
||
函数通过<code>function</code>(“函数”的英文)关键字,并使用圆括号调用。有一些[[ |
函数通过<code>function</code>(“函数”的英文)关键字,并使用圆括号调用。有一些[[语法糖]]可以用来命名函数,局部函数,并且可以作为表中的一个域值。参看[[#Function declarations|函数声明]]和[[#Function calls|函数调用]]。 |
||
Lua函数是[[闭包 (计算机科学)|闭包]],这意味着它们维护对它们声明的作用域的引用,并可以访问和操作该作用域中的变量。 |
Lua函数是[[闭包 (计算机科学)|闭包]],这意味着它们维护对它们声明的作用域的引用,并可以访问和操作该作用域中的变量。 |
||
第342行: | 第341行: | ||
<div id="binop-note" style="padding:0 1em;text-indent: -1em;"><sup>†</sup> 对于二元运算符,Lua首先检查左边的变量的元表(若有),如果左边变量的元方法不存在则寻找右边的变量的元方法。</div> |
<div id="binop-note" style="padding:0 1em;text-indent: -1em;"><sup>†</sup> 对于二元运算符,Lua首先检查左边的变量的元表(若有),如果左边变量的元方法不存在则寻找右边的变量的元方法。</div> |
||
<div id="relop-note" style="padding:0 1em;text-indent: -1em;"><sup>‡</sup> 对于关系运算符,只有当两个参数的元方法都指定了同一个函数时,元表才会被使用。不同的匿名函数,即使具有相同的主体和闭包,也不可能被认为是相同的。</div> |
<div id="relop-note" style="padding:0 1em;text-indent: -1em;"><sup>‡</sup> 对于关系运算符,只有当两个参数的元方法都指定了同一个函数时,元表才会被使用。不同的匿名函数,即使具有相同的主体和闭包,也不可能被认为是相同的。</div> |
||
<div id="metatable-note" style="padding:0 1em;text-indent: -1em;"><sup>*</sup> |
<div id="metatable-note" style="padding:0 1em;text-indent: -1em;"><sup>*</sup> |
||
__metatable会同时影响[[#getmetatable|getmetatable()]]和[[#setmetatable|setmetatable()]]</div> |
__metatable会同时影响[[#getmetatable|getmetatable()]]和[[#setmetatable|setmetatable()]]</div> |
||
</div> |
</div> |
||
第709行: | 第708行: | ||
注意,这里的冒号符号与[[#Function calls|函数调用]]的冒号符号相类似,在参数列表的开头添加了一个隐式参数,名为<code>self</code>。 |
注意,这里的冒号符号与[[#Function calls|函数调用]]的冒号符号相类似,在参数列表的开头添加了一个隐式参数,名为<code>self</code>。 |
||
===错误处理=== |
=== 错误处理 === |
||
错误可以通过[[#error|error()]]和[[#assert|assert()]]“抛出”,使用[[#pcall|pcall()]] 或者[[#xpcall|xpcall()]]可以“捕获”错误。注意,某些Scribunto的内部错误是不能被Lua层面的代码捕获处理。 |
错误可以通过[[#error|error()]]和[[#assert|assert()]]“抛出”,使用[[#pcall|pcall()]] 或者[[#xpcall|xpcall()]]可以“捕获”错误。注意,某些Scribunto的内部错误是不能被Lua层面的代码捕获处理。 |
||
第853行: | 第852行: | ||
用指定的参数在“保护模式”下调用函数<code>f</code>。这意味着如果在调用<code>f</code>时出错,pcall会返回false与错误消息。如果没有错误发生,pcall会返回true与调用返回的所有值。 |
用指定的参数在“保护模式”下调用函数<code>f</code>。这意味着如果在调用<code>f</code>时出错,pcall会返回false与错误消息。如果没有错误发生,pcall会返回true与调用返回的所有值。 |
||
用[[ |
用[[伪代码]]表示,<code>pcall</code>的定义类似如下: |
||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
第912行: | 第911行: | ||
<code>base</code>是可选的,默认为10,指定解析数字的进位基数。这个基数可以是2到36之间的任何整数。对于大于10,字母A(大小写均可)代表10,B代表11,以此类推,Z代表35。 |
<code>base</code>是可选的,默认为10,指定解析数字的进位基数。这个基数可以是2到36之间的任何整数。对于大于10,字母A(大小写均可)代表10,B代表11,以此类推,Z代表35。 |
||
十进制下,值可以有小数部分,或者以[[ |
十进制下,值可以有小数部分,或者以[[科学计数法]]表示,而且甚至可以以“0x”开头以表示16进制。其他情况,只会接受不带符号的整数。 |
||
==== tostring ==== |
==== tostring ==== |
||
第938行: | 第937行: | ||
这个很像<code>[[#pcall|pcall]]</code>,只是错误消息在返回之前传递到函数<code>errhandler</code>中。 |
这个很像<code>[[#pcall|pcall]]</code>,只是错误消息在返回之前传递到函数<code>errhandler</code>中。 |
||
用[[ |
用[[伪代码]]表示,<code>xpcall</code>的定义类似如下: |
||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
第1,084行: | 第1,083行: | ||
参数<code>m</code>、<code>n</code>可省略,但是如果指定了,则必须能够转化为整数。 |
参数<code>m</code>、<code>n</code>可省略,但是如果指定了,则必须能够转化为整数。 |
||
*没有参数时返回区间<math>[0,1)</math>内的实数。 |
* 没有参数时返回区间<math>[0,1)</math>内的实数。 |
||
*有一个参数时返回区间<math>[1,m]</math>内的整数。 |
* 有一个参数时返回区间<math>[1,m]</math>内的整数。 |
||
*有两个参数时返回区间<math>[m,n]</math>内的整数。 |
* 有两个参数时返回区间<math>[m,n]</math>内的整数。 |
||
注意,如果<code>m</code>或者<code>n</code>小于−2147483648或者大于2147483647,或者<code>n - m</code>大于2147483646,那么输出可能会不正确。 |
注意,如果<code>m</code>或者<code>n</code>小于−2147483648或者大于2147483647,或者<code>n - m</code>大于2147483646,那么输出可能会不正确。 |
||
第1,146行: | 第1,145行: | ||
* hour(0~23) |
* hour(0~23) |
||
* min(0~59) |
* min(0~59) |
||
* sec(0~60,允许[[ |
* sec(0~60,允许[[闰秒]]的情况) |
||
* wday(weekday,Sunday是1) |
* wday(weekday,Sunday是1) |
||
* yday(一年的某一天) |
* yday(一年的某一天) |
||
第1,469行: | 第1,468行: | ||
模式可以包括用小括号括起来的子模式(sub-patterns),描述了“捕获”。匹配成功时,字符串的匹配捕获的子字符串会被存储(被“捕获”)以备使用。捕获是根据左边的括号被标号的。比如,在模式<code>(a*(.)%w(%s*))</code>中,匹配<code>a*(.)%w(%s*)</code>的字符串部分被存储在第一个捕获(所以是第一项),匹配<code>.</code>的字符被捕获,记为第2项,匹配<code>%s*</code>的则是第3项。 |
模式可以包括用小括号括起来的子模式(sub-patterns),描述了“捕获”。匹配成功时,字符串的匹配捕获的子字符串会被存储(被“捕获”)以备使用。捕获是根据左边的括号被标号的。比如,在模式<code>(a*(.)%w(%s*))</code>中,匹配<code>a*(.)%w(%s*)</code>的字符串部分被存储在第一个捕获(所以是第一项),匹配<code>.</code>的字符被捕获,记为第2项,匹配<code>%s*</code>的则是第3项。 |
||
捕获参考可以出现在字符串自身,而返回参考早前被捕获的文本。比如,<code>([a-z])%1</code>会匹配任何一对相同的小写字母,而<code>([a-z])([a-z])([a-z])[a-z]%3%2%1</code>会匹配任何7个字母的[[ |
捕获参考可以出现在字符串自身,而返回参考早前被捕获的文本。比如,<code>([a-z])%1</code>会匹配任何一对相同的小写字母,而<code>([a-z])([a-z])([a-z])[a-z]%3%2%1</code>会匹配任何7个字母的[[回文]]。 |
||
特殊情况,空的捕获<code>()</code>会捕获当前的字符串位置(一个数字)。比如我们对字符串<code>"flaaap"</code>执行模式<code>"()aa()"</code>,那么会有两个捕获:3和5。 |
特殊情况,空的捕获<code>()</code>会捕获当前的字符串位置(一个数字)。比如我们对字符串<code>"flaaap"</code>执行模式<code>"()aa()"</code>,那么会有两个捕获:3和5。 |
||
第1,538行: | 第1,537行: | ||
<code>mw.addWarning( text )</code> |
<code>mw.addWarning( text )</code> |
||
在预览编辑时加一个警告信息。<code>text</code>解析为 |
在预览编辑时加一个警告信息。<code>text</code>解析为wikitext。 |
||
==== mw.allToString ==== |
==== mw.allToString ==== |
||
第1,608行: | 第1,607行: | ||
注意没有框架库,也没有叫做<code>frame</code>的全局变量。框架对象通常为被<code><nowiki>{{#invoke:}}</nowiki></code>调用的函数的参数,当然也可以从<code>[[#mw.getCurrentFrame|mw.getCurrentFrame()]]</code>获得。 |
注意没有框架库,也没有叫做<code>frame</code>的全局变量。框架对象通常为被<code><nowiki>{{#invoke:}}</nowiki></code>调用的函数的参数,当然也可以从<code>[[#mw.getCurrentFrame|mw.getCurrentFrame()]]</code>获得。 |
||
==== frame.args ==== |
==== frame.args ==== |
||
用来访问传递到frame的参数的表。例如,一个模块从如下的 |
用来访问传递到frame的参数的表。例如,一个模块从如下的wikitext调用 |
||
<nowiki>{{#invoke:module|function|arg1|arg2|name=arg3}}</nowiki> |
<nowiki>{{#invoke:module|function|arg1|arg2|name=arg3}}</nowiki> |
||
那么<code>frame.args[1]</code>会返回<code>"arg1"</code>,<code>frame.args[2]</code>会返回<code>"arg2"</code>,<code>frame.args['name']</code>或<code>frame.args.name</code>会返回<code>"arg3"</code>。在参数列表迭代可以使用<code>pairs( frame.args )</code>或<code>ipairs( frame.args )</code>。 |
那么<code>frame.args[1]</code>会返回<code>"arg1"</code>,<code>frame.args[2]</code>会返回<code>"arg2"</code>,<code>frame.args['name']</code>或<code>frame.args.name</code>会返回<code>"arg3"</code>。在参数列表迭代可以使用<code>pairs( frame.args )</code>或<code>ipairs( frame.args )</code>。 |
||
然而由于Lua实现表迭代器,迭代的顺序不确定,参数出现在 |
然而由于Lua实现表迭代器,迭代的顺序不确定,参数出现在wikitext中的顺序也无从得知。 |
||
注意这个表中的值总是为字符串,<code>[[#tonumber|tonumber()]]</code>可以用于在需要时转化为数字。但是,键是数字,即使在调用时清楚提供:<code><nowiki>{{#invoke:module|function|1|2=2}}</nowiki></code>给予被数字键<code>1</code>和<code>2</code>索引的字符串值<code>"1"</code>和<code>"2"</code>。 |
注意这个表中的值总是为字符串,<code>[[#tonumber|tonumber()]]</code>可以用于在需要时转化为数字。但是,键是数字,即使在调用时清楚提供:<code><nowiki>{{#invoke:module|function|1|2=2}}</nowiki></code>给予被数字键<code>1</code>和<code>2</code>索引的字符串值<code>"1"</code>和<code>"2"</code>。 |
||
第1,633行: | 第1,632行: | ||
调用解析器函数,返回适当的字符串。这相比于<code>frame:preprocess</code>更优,但如果有可能,最好优先使用原生的Lua函数或Scribunto库函数。 |
调用解析器函数,返回适当的字符串。这相比于<code>frame:preprocess</code>更优,但如果有可能,最好优先使用原生的Lua函数或Scribunto库函数。 |
||
以下调用与以下 |
以下调用与以下wikitext基本相同: |
||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
第1,662行: | 第1,661行: | ||
frame:expandTemplate{ title = 'template', args = { 'arg1', 'arg2', name = 'arg3' } } |
frame:expandTemplate{ title = 'template', args = { 'arg1', 'arg2', name = 'arg3' } } |
||
在Lua脚本中的行为大致和<code><nowiki>{{template|arg1|arg2|name=arg3}}</nowiki></code>在 |
在Lua脚本中的行为大致和<code><nowiki>{{template|arg1|arg2|name=arg3}}</nowiki></code>在wikitext中的行为一样。如果页面名没有命名空间前缀,那么函数会认为页面在模板命名空间内。 |
||
注意标题与参数在传递到模版之前并未预处理: |
注意标题与参数在传递到模版之前并未预处理: |
||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
-- 这与 |
-- 这与wikitext{{template|{{!}}}}基本相同 |
||
frame:expandTemplate{ title = 'template', args = { '|' } } |
frame:expandTemplate{ title = 'template', args = { '|' } } |
||
-- 这与 |
-- 这与wikitext{{template|{{((}}!{{))}}}}基本相同 |
||
frame:expandTemplate{ title = 'template', args = { '{{!}}' } } |
frame:expandTemplate{ title = 'template', args = { '{{!}}' } } |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
第1,723行: | 第1,722行: | ||
<code>frame:preprocess{ text = string }</code> |
<code>frame:preprocess{ text = string }</code> |
||
在当前框架环境下展开 |
在当前框架环境下展开wikitext,比如,模板、解析器函数以及像<code><nowiki>{{{1}}}</nowiki></code>这样的参数都会展开。某些特殊的写成XML格式的标记,比如<code><pre></code>、<code><nowiki></code>、<code><gallery></code>和<code><ref></code>都会被替换为“strip marker”——一类特殊的字符串,由删除符(ASCII 127)开头,在从<code>#invoke</code>返回后被替换成HTML。 |
||
如果你使用单个模板,使用[[#frame:expandTemplate|<code>frame:expandTemplate</code>]]而非尝试建造 |
如果你使用单个模板,使用[[#frame:expandTemplate|<code>frame:expandTemplate</code>]]而非尝试建造wikitext以使用这个方法。这样更快且更不容易出错,尤其是参数包含管道符或其他wikitext标记时。 |
||
同理,展开单个解析器函数时应使用[[#frame:callParserFunction|<code>frame:callParserFunction</code>]]。 |
同理,展开单个解析器函数时应使用[[#frame:callParserFunction|<code>frame:callParserFunction</code>]]。 |
||
第1,736行: | 第1,735行: | ||
获得特定参数的对象,或者没有提供参数时返回nil。 |
获得特定参数的对象,或者没有提供参数时返回nil。 |
||
返回的对象有一个方法,<code>object:expand()</code>,可以返回对应参数的展开后的 |
返回的对象有一个方法,<code>object:expand()</code>,可以返回对应参数的展开后的wikitext。 |
||
==== frame:newParserValue ==== |
==== frame:newParserValue ==== |
||
第1,807行: | 第1,806行: | ||
<code>[[#mw.html-object|html]]:wikitext( ... )</code> |
<code>[[#mw.html-object|html]]:wikitext( ... )</code> |
||
给mw.html对象加上不定数量的 |
给mw.html对象加上不定数量的wikitext字符串。 |
||
注意遇到第一个''nil''项就会停。 |
注意遇到第一个''nil''项就会停。 |
||
第1,862行: | 第1,861行: | ||
=== 语言库 === |
=== 语言库 === |
||
语言代码在语言代码中由描述。很多MediaWiki的语言代码类似于[[ |
语言代码在语言代码中由描述。很多MediaWiki的语言代码类似于[[IETF语言标签]],但不是所有MediaWiki语言代码都是有效的IETF标签,反之亦然。 |
||
{{anchor|mw.language-object}} |
{{anchor|mw.language-object}} |
||
第1,893行: | 第1,892行: | ||
==== mw.language.getFallbacksFor ==== |
==== mw.language.getFallbacksFor ==== |
||
[[File:MediaWiki fallback chains.svg| |
[[File:MediaWiki fallback chains.svg|缩略图|备选链]] |
||
<code>mw.language.getFallbacksFor( code )</code> |
<code>mw.language.getFallbacksFor( code )</code> |
||
第2,004行: | 第2,003行: | ||
<code>timestamp</code>的格式字符串和支持的值与[[Extension:ParserFunctions]]的#time解析器函数完全相同。 |
<code>timestamp</code>的格式字符串和支持的值与[[Extension:ParserFunctions]]的#time解析器函数完全相同。 |
||
注意虽然反斜杠可能需要在Lua字符串字面量中写两次,由于Lua也使用反斜杠转义,而 |
注意虽然反斜杠可能需要在Lua字符串字面量中写两次,由于Lua也使用反斜杠转义,而wikitext不需要: |
||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
第2,134行: | 第2,133行: | ||
<code>mw.message.rawParam( value )</code> |
<code>mw.message.rawParam( value )</code> |
||
包装(wrap)该值使之不会被<code>[[#mw.message:parse|msg:parse()]]</code>解析为 |
包装(wrap)该值使之不会被<code>[[#mw.message:parse|msg:parse()]]</code>解析为wikitext。 |
||
==== mw.message.numParam ==== |
==== mw.message.numParam ==== |
||
第2,194行: | 第2,193行: | ||
<code>[[#mw.message-object|msg]]:plain()</code> |
<code>[[#mw.message-object|msg]]:plain()</code> |
||
替换参数按原样返回消息 |
替换参数按原样返回消息wikitext。模板调用和解析器函数都是完整的。 |
||
==== mw.message:exists ==== |
==== mw.message:exists ==== |
||
第2,211行: | 第2,210行: | ||
返回表示消息键是否被禁用的布尔值。如果消息键不存在,或者消息是空字符串,或者是字符串"-"则返回true。 |
返回表示消息键是否被禁用的布尔值。如果消息键不存在,或者消息是空字符串,或者是字符串"-"则返回true。 |
||
===站点信息库 === |
=== 站点信息库 === |
||
==== mw.site.currentVersion ==== |
==== mw.site.currentVersion ==== |
||
第2,235行: | 第2,234行: | ||
* '''id''':命名空间数字。 |
* '''id''':命名空间数字。 |
||
* '''name''':本地命名空间名称。 |
* '''name''':本地命名空间名称。 |
||
*'''canonicalName''':规范(canonical)命名空间名称。 |
* '''canonicalName''':规范(canonical)命名空间名称。 |
||
* '''displayName''':为命名空间0设置,用于显示的名称(因为这个名称通常是空白字符串)。 |
* '''displayName''':为命名空间0设置,用于显示的名称(因为这个名称通常是空白字符串)。 |
||
* '''hasSubpages''':这个命名空间是否启用了子页面。 |
* '''hasSubpages''':这个命名空间是否启用了子页面。 |
||
第2,308行: | 第2,307行: | ||
* '''prefix'''——跨wiki前缀。 |
* '''prefix'''——跨wiki前缀。 |
||
* '''url'''——跨wiki指向的URL。页面名称由参数$1体现。 |
* '''url'''——跨wiki指向的URL。页面名称由参数$1体现。 |
||
* '''isProtocalRelative'''——布尔值,显示URL是否为[[ |
* '''isProtocalRelative'''——布尔值,显示URL是否为[[URL]]。 |
||
* '''isLocal'''——这个URL是否是当前wiki的站点的。 |
* '''isLocal'''——这个URL是否是当前wiki的站点的。 |
||
* '''isCurrentWiki'''——这个URL是否是为当前wiki的。 |
* '''isCurrentWiki'''——这个URL是否是为当前wiki的。 |
||
第2,325行: | 第2,324行: | ||
<code>mw.text.decode( s, decodeNamedEntities )</code> |
<code>mw.text.decode( s, decodeNamedEntities )</code> |
||
将字符串中的[[ |
将字符串中的[[HTML元素]]替换为对应的字符。 |
||
如果布尔值<code>decodeNameEntities</code>被省略或者为false,则只有被命名的实体“&lt;”“&gt;”“&amp;”“&quot;”和“&nbsp;”会被认可。否则,认可的HTML5命名实体的列表会从PHP的[https://php.net/get_html_translation_table <code>get_html_translation_table</code>]函数中加载。 |
如果布尔值<code>decodeNameEntities</code>被省略或者为false,则只有被命名的实体“&lt;”“&gt;”“&amp;”“&quot;”和“&nbsp;”会被认可。否则,认可的HTML5命名实体的列表会从PHP的[https://php.net/get_html_translation_table <code>get_html_translation_table</code>]函数中加载。 |
||
第2,334行: | 第2,333行: | ||
<code>mw.text.encode( s, charset )</code> |
<code>mw.text.encode( s, charset )</code> |
||
使用[[ |
使用[[HTML实体]]替换字符串中的字符。字符“<”“>”“&”“"”和非换行空格会被适当的命名实体替换,所有其他的都会被替换为数字实体。 |
||
如果提供了<code>charset</code>,则它应该是合适的字符串,且被[[#Ustring patterns|Ustring模式]]的括号括住,比如<code>[set]</code>中的“set”。默认的charset是<code>'<>&"\' '</code>(末尾的空格为非换行空格,U+00A0)。 |
如果提供了<code>charset</code>,则它应该是合适的字符串,且被[[#Ustring patterns|Ustring模式]]的括号括住,比如<code>[set]</code>中的“set”。默认的charset是<code>'<>&"\' '</code>(末尾的空格为非换行空格,U+00A0)。 |
||
第2,354行: | 第2,353行: | ||
* JSON对象会丢弃含有null值的键。 |
* JSON对象会丢弃含有null值的键。 |
||
* 不能直接分辨带有序列整数键的是JSON数组还是JSON对象。 |
* 不能直接分辨带有序列整数键的是JSON数组还是JSON对象。 |
||
* 带有序列整数键从1开始 |
* 带有序列整数键从1开始的JSON对象会被解析到作为有相同值的JSON数组的相同的表结构,尽管这些不一定总是相等,除非使用了<code>mw.text.JSON_PRESERVE_KEYS</code>。 |
||
==== mw.text.jsonEncode ==== |
==== mw.text.jsonEncode ==== |
||
第2,408行: | 第2,407行: | ||
<code>mw.text.nowiki( s )</code> |
<code>mw.text.nowiki( s )</code> |
||
使用[[ |
使用[[HTML实体]]替换字符串中的多种字符,以避免被解析为wikitext。包括: |
||
* 以下字符:<code>"</code>、<code>&</code>、<code>'</code>、<code><</code>、<code>=</code>、<code>></code>、<code>[</code>、<code>]</code>、<code>{</code>、<code>|</code>、<code>}</code> |
* 以下字符:<code>"</code>、<code>&</code>、<code>'</code>、<code><</code>、<code>=</code>、<code>></code>、<code>[</code>、<code>]</code>、<code>{</code>、<code>|</code>、<code>}</code> |
||
* 字符串开头或新行后面 |
* 字符串开头或新行后面的以下字符:<code>#</code>、<code>*</code>、<code>:</code>、<code>;</code>、空格、制表符('\t') |
||
* 空行会有关联的新行或返回转义的字符(Blank lines will have one of the associated newline or carriage return characters escaped) |
* 空行会有关联的新行或返回转义的字符(Blank lines will have one of the associated newline or carriage return characters escaped) |
||
* 字符串开始处或新行后 |
* 字符串开始处或新行后的<code>----</code>会使得第一个<code>-</code>被转义 |
||
* <code>__</code>会使一个下划线被转义 |
* <code>__</code>会使一个下划线被转义 |
||
* <code>://</code>会使冒号被转义 |
* <code>://</code>会使冒号被转义 |
||
第2,556行: | 第2,555行: | ||
* '''subpageText''':如果这是个子页面,子页面名称。否则,和<code>title.text</code>相同。 |
* '''subpageText''':如果这是个子页面,子页面名称。否则,和<code>title.text</code>相同。 |
||
* '''canTalk''':这个标题的页面能否拥有讨论页。 |
* '''canTalk''':这个标题的页面能否拥有讨论页。 |
||
*'''exists''':该页面是否存在。Media命名空间页面的<code>file.exists</code>别名。对于File命名空间的页面,这将检查文件描述页面的存在,而不是文件本身。{{red|此函数[[#Expensive properties|可能为高开销]]}}。 |
* '''exists''':该页面是否存在。Media命名空间页面的<code>file.exists</code>别名。对于File命名空间的页面,这将检查文件描述页面的存在,而不是文件本身。{{red|此函数[[#Expensive properties|可能为高开销]]}}。 |
||
*'''file''','''fileExists''':参见下面的[[#File metadata|#文件元数据]]。 |
* '''file''','''fileExists''':参见下面的[[#File metadata|#文件元数据]]。 |
||
* '''isContentPage''':这个页面是否在内容命名空间内。 |
* '''isContentPage''':这个页面是否在内容命名空间内。 |
||
* '''isExternal''':此页面是否具有跨wiki的前缀。 |
* '''isExternal''':此页面是否具有跨wiki的前缀。 |
||
* '''isLocal''':此页面是否在此项目中。例如,在英语维基百科上,任何其他语言维基百科都被视为“本地”(Local),而维基 |
* '''isLocal''':此页面是否在此项目中。例如,在英语维基百科上,任何其他语言维基百科都被视为“本地”(Local),而维基词典等则被视为非“本地”。 |
||
* '''isRedirect''':是否是重定向页面的标题。{{red|此函数[[#Expensive properties|可能为高开销]]}}。 |
* '''isRedirect''':是否是重定向页面的标题。{{red|此函数[[#Expensive properties|可能为高开销]]}}。 |
||
* '''isSpecialPage''':该页面是否可能是特殊页面(即“Special”命名空间中的页面)。 |
* '''isSpecialPage''':该页面是否可能是特殊页面(即“Special”命名空间中的页面)。 |
||
第2,599行: | 第2,598行: | ||
* '''pages''':如果文件格式支持多页,这是包含文件每个页面的表,否则为<code>nil</code>。[[#Length operator|“#”操作符]]可以用于获取文件页数。每个单独的页面表都包含一个width和height属性。 |
* '''pages''':如果文件格式支持多页,这是包含文件每个页面的表,否则为<code>nil</code>。[[#Length operator|“#”操作符]]可以用于获取文件页数。每个单独的页面表都包含一个width和height属性。 |
||
* '''size''':文件的字节长度。 |
* '''size''':文件的字节长度。 |
||
* '''mimeType''':文件的[[ |
* '''mimeType''':文件的[[MIME类型]]。 |
||
* '''length''':媒体文件的长度,单位为秒。不支持长度的媒体则为0。 |
* '''length''':媒体文件的长度,单位为秒。不支持长度的媒体则为0。 |
||
第2,613行: | 第2,612行: | ||
<code>mw.uri.encode( s, enctype )</code> |
<code>mw.uri.encode( s, enctype )</code> |
||
[[ |
[[百分号编码]]字符串。默认类型,<code>"QUERY"</code>,使用“+”编码空格以用于查询字符;<code>"PATH"</code>将空格编码为%20,<code>"WIKI"</code>将空格编码为“_”。 |
||
注意"WIKI"格式不是完全可以逆转的,因为空格和下划线都会编码为“_”。 |
注意"WIKI"格式不是完全可以逆转的,因为空格和下划线都会编码为“_”。 |
||
第2,851行: | 第2,850行: | ||
bit32 = require( 'bit32' ) |
bit32 = require( 'bit32' ) |
||
bit32库提供了无符号的32位整数的[[ |
bit32库提供了无符号的32位整数的[[位运算]]。输入的整数会被截成整数(方法未指定)并用2<sup>32</sup>模除,这样值就是在0到2<sup>32</sup>-1之间的,返回的值也会是这个范围。 |
||
如果字节被编号(就像[[#bit32.extract|bit32.extract()]]中那样),那么0是最低位的字节(带有值2<sup>0</sup>的),31是最高位的(带有值2<sup>31</sup>的)。 |
如果字节被编号(就像[[#bit32.extract|bit32.extract()]]中那样),那么0是最低位的字节(带有值2<sup>0</sup>的),31是最高位的(带有值2<sup>31</sup>的)。 |
||
第2,917行: | 第2,916行: | ||
<code>bit32.arshift( n, disp )</code> |
<code>bit32.arshift( n, disp )</code> |
||
返回数<code>n</code>向右[[位操作#移位|移动]]<code>disp</code>位。这是一个[[ |
返回数<code>n</code>向右[[位操作#移位|移动]]<code>disp</code>位。这是一个[[算数移位]]:如果<code>disp</code>是正的,那么插入的位将会与原始数字的31位相同。 |
||
注意超过31的移位将会导致0或4294967295。 |
注意超过31的移位将会导致0或4294967295。 |
||
第3,066行: | 第3,065行: | ||
== 与标准Lua的不同之处 == |
== 与标准Lua的不同之处 == |
||
===改变的函数=== |
=== 改变的函数 === |
||
以下函数被'''修改'''了: |
以下函数被'''修改'''了: |
||
第3,082行: | 第3,081行: | ||
以下包被'''几乎移除'''。只有列出来的函数可用。 |
以下包被'''几乎移除'''。只有列出来的函数可用。 |
||
; |
; [https://www.lua.org/manual/5.1/manual.html#5.3 package.*]: 文件系统和对C库的取得被移除了。 可用的函数和表为: |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-package.loaded package.loaded] |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-package.loaded package.loaded] |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-package.preload package.preload] |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-package.preload package.preload] |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-package.loaders package.loaders]: 可获取本地文件系统或加载C库的加载器不存在。 添加了Module命名空间页面的加载器。 |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-package.loaders package.loaders]: 可获取本地文件系统或加载C库的加载器不存在。 添加了Module命名空间页面的加载器。 |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-package.seeall package.seeall()] |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-package.seeall package.seeall()] |
||
; |
; [https://www.lua.org/manual/5.1/manual.html#5.8 os.*]: 有些不安全的函数,例如os.execute(),因而不被允许。 可用的函数为: |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-os.clock os.clock()] |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-os.clock os.clock()] |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-os.date os.date()] |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-os.date os.date()] |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-os.difftime os.difftime()] |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-os.difftime os.difftime()] |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-os.time os.time()] |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-os.time os.time()] |
||
; |
; [https://www.lua.org/manual/5.1/manual.html#5.9 debug.*]: 大多数函数都是不安全的。 可用的函数为: |
||
:; [https://www.lua.org/manual/5.1/manual.html#pdf-debug.traceback debug.traceback()] |
:; [https://www.lua.org/manual/5.1/manual.html#pdf-debug.traceback debug.traceback()] |
||
第3,166行: | 第3,165行: | ||
Scribunto扩展包括一个用于测试用例的基类<code>Scribunto_LuaEngineTestBase</code>,该类将针对LuaSandbox和LuaStandalone引擎运行测试。 |
Scribunto扩展包括一个用于测试用例的基类<code>Scribunto_LuaEngineTestBase</code>,该类将针对LuaSandbox和LuaStandalone引擎运行测试。 |
||
库的测试用例应该扩展这个类,并且不应该覆盖<code>static function suite()</code>。 |
库的测试用例应该扩展这个类,并且不应该覆盖<code>static function suite()</code>。 |
||
在Scribunto扩展中,测试用例应该在<code>tests/engines/LuaCommon/''Name''LibraryTest.php</code>并添加到{{phpi|ScribuntoHooks::unitTestsList()}}中的数组中(在<code>common/Hooks.php</code>中),扩展应该在自己的<code>[[Manual:Hooks/UnitTestsList|UnitTestsList]]</code>钩子函数中添加测试用例,可能取决于是否设置了<code>$wgAutoloadClasses['Scribunto_LuaEngineTestBase']</code>。 |
在Scribunto扩展中,测试用例应该在<code>tests/engines/LuaCommon/''Name''LibraryTest.php</code>并添加到{{phpi|ScribuntoHooks::unitTestsList()}}中的数组中(在<code>common/Hooks.php</code>中),扩展应该在自己的<code>[[mw:Manual:Hooks/UnitTestsList|UnitTestsList]]</code>钩子函数中添加测试用例,可能取决于是否设置了<code>$wgAutoloadClasses['Scribunto_LuaEngineTestBase']</code>。 |
||
大多数时候,制作测试用例需要做的包括: |
大多数时候,制作测试用例需要做的包括: |
||
第3,212行: | 第3,211行: | ||
有(至少)两种方式来运行PHPUnit测试: |
有(至少)两种方式来运行PHPUnit测试: |
||
# 针对核心运行phpunit,允许tests/phpunit/suites/ExtensionsTestSuite.php使用[[Manual:Hooks/UnitTestsList|UnitTestsList]]钩子找到扩展的测试。 如果您的扩展的测试类名称都包含一个唯一的组件(例如扩展的名称),则可以使用<code>--filter</code>选项以仅运行您的扩展的测试。 |
# 针对核心运行phpunit,允许tests/phpunit/suites/ExtensionsTestSuite.php使用[[mw:Manual:Hooks/UnitTestsList|UnitTestsList]]钩子找到扩展的测试。 如果您的扩展的测试类名称都包含一个唯一的组件(例如扩展的名称),则可以使用<code>--filter</code>选项以仅运行您的扩展的测试。 |
||
# 对扩展目录运行phpunit,这将获取以“Test.php”结尾的任何文件。 |
# 对扩展目录运行phpunit,这将获取以“Test.php”结尾的任何文件。 |
||
第3,231行: | 第3,230行: | ||
Scribunto中包含的模块应该在上面的[[#Scribunto libraries|Scribunto库]]部分中包含文档。扩展库应该在其自己的扩展页面的子页面中包含文档,并从上方的[[#Extension library|扩展库]]章节中链接到该文档。 |
Scribunto中包含的模块应该在上面的[[#Scribunto libraries|Scribunto库]]部分中包含文档。扩展库应该在其自己的扩展页面的子页面中包含文档,并从上方的[[#Extension library|扩展库]]章节中链接到该文档。 |
||
==参见== |
== 参见 == |
||
* [[Lua]] |
* [[Lua]] |
||
第3,244行: | 第3,243行: | ||
{{-}} |
{{-}} |
||
{{帮助页面}} |
{{帮助页面}} |
||
[[Category:帮助文档]] |
[[Category:帮助文档]] |