- Welcome to Touhou Wiki!
- Registering is temporarily disabled. Check in our Discord server to request an account and for assistance of any kind.
Module:Common: Difference between revisions
DennouNeko (talk | contribs) m (category) |
DennouNeko (talk | contribs) m (1 revision: updates for most recent version of Scribunto) |
||
(11 intermediate revisions by 3 users not shown) | |||
Line 3: | Line 3: | ||
To use all the functions NOT defined as local, add at the beginning of script the following: | To use all the functions NOT defined as local, add at the beginning of script the following: | ||
require("Module:Common") | require("Module:Common") | ||
The names aren't being sorted, because this could break the function dependencies. | |||
--]] | --]] | ||
-- create global object "common" for most of exported functions | -- create global object "common" for most of exported functions | ||
common = {} | local common = {} | ||
-- == constants == | |||
common.romanizable = {'zh-hans', 'zh-hant', 'zh-cn', 'zh-tw', 'zh-hk', 'zh-sg', 'zh-mo', 'zh-my', 'ja', 'ko', 'vi'} | |||
-- Note: There's a full-width space to space conversion. Don't remove it! | |||
common.normalization_table = {[' '] = ' ', ['~'] = '~', ['!'] = '!', ['?'] = '?'} | |||
-- == helper functions == | |||
-- checks if string is set and if it's non-empty | -- checks if string is set and if it's non-empty | ||
function isset(target) | function common.isset(target) | ||
return target ~= nil and target ~= "" | return target ~= nil and target ~= "" | ||
end | end | ||
-- | --[[ simulates the (a ? b : c) notation of C/C++ and PHP languages. | ||
function | Similar to {{#if:{{{a|}}}|{{{b|}}}|{{{c|}}}}} from parser functions. ]] | ||
return | function common.cv(a, b, c) | ||
if a then return b else return c end | |||
end | end | ||
-- | --slices a table to return another table containing values within a certain range | ||
function | --source: http://snippets.luacode.org/snippets/Table_Slice_116 | ||
function common.sliceTable (values,i1,i2) | |||
local res = {} | |||
local n = #values | |||
-- default values for range | |||
i1 = i1 or 1 | |||
i2 = i2 or n | |||
if i2 < 0 then | |||
i2 = n + i2 + 1 | |||
elseif i2 > n then | |||
i2 = n | |||
end | |||
if i1 < 1 or i1 > n then | |||
return {} | |||
end | |||
local k = 1 | |||
for i = i1,i2 do | |||
res[k] = values[i] | |||
k = k + 1 | |||
end | |||
return res | |||
end | end | ||
-- checks if a given page exists | -- checks if a given page exists | ||
function | function common.exists(page) | ||
if not isset(page) then return false end | if not common.isset(page) then return false end | ||
return mw.getCurrentFrame():preprocess('{{#ifexist:' .. page .. '|1|0}}') == '1' | return mw.getCurrentFrame():preprocess('{{#ifexist:' .. page .. '|1|0}}') == '1' | ||
end | end | ||
-- [[ | --[[ Tries to get contents of a page with given name. | ||
If the function fails it returns nil (page doesn't exist or can't be loaded) | |||
On success it returns the contents of page (it can be be partially preprocessed, so watch out for parser markers). ]] | |||
function common.getPage(name) | |||
if not common.isset(name) then return nil end | |||
local frame = mw.getCurrentFrame() | |||
-- do a safe call to catch possible errors, like "template doesn't exist" | |||
local stat,page = pcall(frame.expandTemplate, frame, {title = ':' .. name}) | |||
if not stat then | |||
-- TODO: 'page' contains the error message. Do some debugging? | |||
return nil | |||
end | |||
return page | |||
end | |||
function common.stripTags(text) | |||
if common.isset(text) then | |||
local tmp | |||
repeat | |||
tmp = text | |||
-- a pair of tags, like <td style="">...</td> | |||
text = string.gsub(text, '<%s*(%w+).->(.-)<%s*/%s*%1%s*>', '%2') | |||
-- closed tag, like <br/> | |||
text = string.gsub(text, '<%s*%w+%s*/%s*>', '') | |||
until tmp == text | |||
end | |||
return text | |||
end | |||
--[[ Sort table and remove repeating elements. | |||
Since tbl is passed as reference, any changes in it will affect the passed table. ]] | |||
function common.trunkTable(tbl) | |||
table.sort(tbl) | |||
local last | |||
local redo | |||
repeat | |||
redo = false | |||
last = nil | |||
for k,v in pairs(tbl) do | |||
if v ~= last then | |||
last = v | |||
else | |||
table.remove(tbl, k) | |||
redo = true | |||
break | |||
end | |||
end | |||
until not redo | |||
end | |||
--[[ Checks if a given value is among the elements of a table and returns its index. | |||
Returns nil if it can't find it. ]] | |||
function common.isInTable(tbl, val) | |||
for k,v in pairs(tbl) do | |||
if v == val then return k end | |||
end | |||
return nil | |||
end | |||
--[[ Compare 'n' elements in two tables, starting from 's1' in first table and 's2' in second table. ]] | |||
function common.partialTableCompare(t1, t2, s1, s2, n) | |||
if n < 1 then return true end -- basically there's nothing to compare, so no differences were found | |||
for i = 0,(n-1) do | |||
-- Note that nil values are also valid. | |||
if t1[s1+i] ~= t2[s2+i] then return false end | |||
end | |||
return true | |||
end | |||
return common |
Latest revision as of 16:10, 8 August 2013
Add the following code before using any of the functions from the "Common" library.
local common = require("Module:Common")
General notes for all modules:
- Don't remove functions without discussing it first. A lot of scripts may break if you do so.
- Before adding any new functions, test it first if there are no syntax errors, so the new fragment of code won't break scripts that are using this library.
- When modifying existing functions, make sure that the new version is compatible with old one. Any modification may only extend functionality, but can't reduce or change behavior of current version.
- Creation of global functions and variables is no longer possible. Everything that's going to be exported has to be returned at the end of module.
- Once again, test it before doing any modifications.
The names are being sorted in alphabetical order.
cv(a, b, c)
Useful in cases, when we have to choose one of 2 values to pass to same variable or table element.
If a evaluates to true then function will return b, otherwise it'll return c.
Part of code like
local tbl = {}
if condition then
tbl[#tbl+1] = 'TRUE'
else
tbl[#tbl+1] = 'FALSE'
end
can be simplified to
local tbl = {}
tbl[#tbl+1] = common.cv(condition, 'TRUE', 'FALSE')
exists(name)
Checks if given Touhou Wiki page exists. It uses the expensive preprocessor function {{#ifexist:Page name}}. Limit of expensive function calls for Touhou Wiki is currently 100. If that number is exceeded then for next calls exists will return false, whether page exists or not.
common.exists("Touhou Wiki")
will return true, unless the main page is going to be moved or deleted.
common.exists("Module:Common")
will return true or you'll get a nice, red "Script error" (unless you've implemented own exists).
getPage(name)
Tries to get contents of a given page. No expensive functions are being used.
This function will most probably fail for most of special pages, so it's generally usable for article pages.
If a given page doesn't exist or contents can't be retrieved, it'll return nil.
For example, following code will return the partially preprocessed text for main page:
local main = common.getPage("Touhou Wiki")
Page's content is partially preprocessed, so watch out for strip markers, especially in section headers. These are unique strings that start and end with 'DEL' character (127, 0x7f) and look like ⌦UNIQ3fc7e69e5822d9c0-nowiki-00000001-QINU⌫ (where ⌦ and ⌫ are starting and ending 'DEL' characters).
When retrieving page contents, section header == Documentation == is actually returned as text similar to ==⌦UNIQ3fc7e69e5822d9c0-h-6--QINU⌫ Documentation ==.
Usually it's not visible, because it's stripped from text displayed to users, but it's something to keep in mind when processing page contents in Lua (for example when searching for specific header).
Following code was used to expose the strip markers:
string.gsub(content, "%\127(UNIQ.-QINU)%\127", "⌦%1⌫")
isInTable(tbl, val)
Checks if given element exists in table and returns it's index. Returns nil if the element can't be found.
isset(val)
It will return false if passed argument is a nil value (undefined variable) or an empty string, and true in any other case.
partialTableCompare(tbl1, tbl2, s1, s2, n)
Compares n elements of two numbered tables, tbl1 and tbl2, starting with element s1 in table tbl1 and s2 in table tbl2 and returns true when appropriate elements in this range are equal, false if there's at least one difference.
In case that n=0 it'll return true, because it didn't find any differences.
stripTags(text)
Removes any valid HTML code from given string. It works only for proper pairs of opening and closing tags (like <div> </div>) or for closed tags (like <br/>).
sliceTable(values, i1, i2)
"Given a Lua table, extract a sub-array or slice. This function works like string.sub: if the end of the range is not specified, then everything up to the end is assumed; this argument can also be a negative number, where -1 is the end, -2 second-last, etc."
Source: http://snippets.luacode.org/snippets/Table_Slice_116
trunkTable(tbl)
The given table is sorted (using table.sort) and repeating elements are being removed. It directly modifies the passed table and no value is returned.
--[[
Library for all the functions that are going to be shared by other scripts.
To use all the functions NOT defined as local, add at the beginning of script the following:
require("Module:Common")
The names aren't being sorted, because this could break the function dependencies.
--]]
-- create global object "common" for most of exported functions
local common = {}
-- == constants ==
common.romanizable = {'zh-hans', 'zh-hant', 'zh-cn', 'zh-tw', 'zh-hk', 'zh-sg', 'zh-mo', 'zh-my', 'ja', 'ko', 'vi'}
-- Note: There's a full-width space to space conversion. Don't remove it!
common.normalization_table = {[' '] = ' ', ['~'] = '~', ['!'] = '!', ['?'] = '?'}
-- == helper functions ==
-- checks if string is set and if it's non-empty
function common.isset(target)
return target ~= nil and target ~= ""
end
--[[ simulates the (a ? b : c) notation of C/C++ and PHP languages.
Similar to {{#if:{{{a|}}}|{{{b|}}}|{{{c|}}}}} from parser functions. ]]
function common.cv(a, b, c)
if a then return b else return c end
end
--slices a table to return another table containing values within a certain range
--source: http://snippets.luacode.org/snippets/Table_Slice_116
function common.sliceTable (values,i1,i2)
local res = {}
local n = #values
-- default values for range
i1 = i1 or 1
i2 = i2 or n
if i2 < 0 then
i2 = n + i2 + 1
elseif i2 > n then
i2 = n
end
if i1 < 1 or i1 > n then
return {}
end
local k = 1
for i = i1,i2 do
res[k] = values[i]
k = k + 1
end
return res
end
-- checks if a given page exists
function common.exists(page)
if not common.isset(page) then return false end
return mw.getCurrentFrame():preprocess('{{#ifexist:' .. page .. '|1|0}}') == '1'
end
--[[ Tries to get contents of a page with given name.
If the function fails it returns nil (page doesn't exist or can't be loaded)
On success it returns the contents of page (it can be be partially preprocessed, so watch out for parser markers). ]]
function common.getPage(name)
if not common.isset(name) then return nil end
local frame = mw.getCurrentFrame()
-- do a safe call to catch possible errors, like "template doesn't exist"
local stat,page = pcall(frame.expandTemplate, frame, {title = ':' .. name})
if not stat then
-- TODO: 'page' contains the error message. Do some debugging?
return nil
end
return page
end
function common.stripTags(text)
if common.isset(text) then
local tmp
repeat
tmp = text
-- a pair of tags, like <td style="">...</td>
text = string.gsub(text, '<%s*(%w+).->(.-)<%s*/%s*%1%s*>', '%2')
-- closed tag, like <br/>
text = string.gsub(text, '<%s*%w+%s*/%s*>', '')
until tmp == text
end
return text
end
--[[ Sort table and remove repeating elements.
Since tbl is passed as reference, any changes in it will affect the passed table. ]]
function common.trunkTable(tbl)
table.sort(tbl)
local last
local redo
repeat
redo = false
last = nil
for k,v in pairs(tbl) do
if v ~= last then
last = v
else
table.remove(tbl, k)
redo = true
break
end
end
until not redo
end
--[[ Checks if a given value is among the elements of a table and returns its index.
Returns nil if it can't find it. ]]
function common.isInTable(tbl, val)
for k,v in pairs(tbl) do
if v == val then return k end
end
return nil
end
--[[ Compare 'n' elements in two tables, starting from 's1' in first table and 's2' in second table. ]]
function common.partialTableCompare(t1, t2, s1, s2, n)
if n < 1 then return true end -- basically there's nothing to compare, so no differences were found
for i = 0,(n-1) do
-- Note that nil values are also valid.
if t1[s1+i] ~= t2[s2+i] then return false end
end
return true
end
return common