Line 23: |
Line 23: |
| | | |
| -- * Collection functions. | | -- * Collection functions. |
| + | |
| + | function Utils.isize(xs) |
| + | local r = 0 |
| + | for _ in ipairs(xs) do |
| + | r = r + 1 |
| + | end |
| + | return r |
| + | end |
| + | |
| + | function Utils.size(xs) |
| + | local r = 0 |
| + | for _ in pairs(xs) do |
| + | r = r + 1 |
| + | end |
| + | return r |
| + | end |
| + | |
| + | function Utils.removekey(xs, k) |
| + | local e = xs[k] |
| + | xs[k] = nil |
| + | return e |
| + | end |
| | | |
| function Utils.isArray(xs) | | function Utils.isArray(xs) |
Line 124: |
Line 146: |
| end | | end |
| | | |
− | function Utils.imax(arr) | + | function Utils.imax(arr, def) |
| local maxValue | | local maxValue |
| local maxIndex | | local maxIndex |
Line 133: |
Line 155: |
| end | | end |
| end | | end |
− | return maxValue | + | return maxValue or def |
| end | | end |
| | | |
− | function Utils.imin(arr) | + | function Utils.imin(arr, def) |
| local minValue | | local minValue |
| local minIndex | | local minIndex |
Line 145: |
Line 167: |
| end | | end |
| end | | end |
− | return minValue | + | return minValue or def |
| end | | end |
| | | |
Line 170: |
Line 192: |
| return k, v | | return k, v |
| end | | end |
| + | end |
| + | |
| + | function Utils.ilast(arr) |
| + | return arr[#arr] |
| end | | end |
| | | |
Line 200: |
Line 226: |
| end | | end |
| | | |
− | function Utils.isort(arr) | + | function Utils.sort(tbl, f) |
| + | table.sort(tbl, f) |
| + | return tbl |
| + | end |
| + | |
| + | function Utils.isort(arr, f) |
| local result = Utils.icopy(arr) | | local result = Utils.icopy(arr) |
− | table.sort(result) | + | table.sort(result, f) |
| return result | | return result |
| end | | end |
Line 313: |
Line 344: |
| local success, data = pcall(function () return require(string.format("Module:%s", name)) end) | | local success, data = pcall(function () return require(string.format("Module:%s", name)) end) |
| -- module without return (or empty, nil, false, true return) gives success = true, data = true | | -- module without return (or empty, nil, false, true return) gives success = true, data = true |
| + | if data == true then |
| + | return false, nil |
| + | else |
| + | return success, data |
| + | end |
| + | end |
| + | |
| + | function Utils.loadData(name) |
| + | local success, data = pcall(function () return mw.loadData(string.format("Module:%s", name)) end) |
| + | -- TODO: ??? |
| if data == true then | | if data == true then |
| return false, nil | | return false, nil |
Line 478: |
Line 519: |
| | | |
| return result | | return result |
| + | end |
| + | |
| + | Utils.romanizable = {'zh-hans', 'zh-hant', 'zh-cn', 'zh-tw', 'zh-hk', 'zh-sg', 'zh-mo', 'zh-my', 'ja', 'ko', 'vi'} |
| + | |
| + | Utils.normalization_table = {[' '] = ' ', ['~'] = '~', ['!'] = '!', ['?'] = '?'} |
| + | |
| + | -- checks if string is set and if it's non-empty |
| + | function Utils.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 Utils.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 Utils.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 Utils.exists(page) |
| + | if not Utils.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 Utils.getPage(name) |
| + | if not Utils.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 Utils.stripTags(text) |
| + | if Utils.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 Utils.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 Utils.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 Utils.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 |
| + | |
| + | -- naming based on "Navbox" elements |
| + | Utils.main_colors = { |
| + | game = {border = '#A88580', title = '#FFC9C2', above = '#FFD1CA', group = '#FFD9D2', subgroup = '#FFE1DA', dark = '#FFEEE8', background = '#FFF4EE'}; |
| + | music = {border = '#A8A077', title = '#FFF3B4', above = '#FFF6C0', group = '#FFF7C8', subgroup = '#FFF8D0', dark = '#FFFBE4', background = '#FFFBEE'}; |
| + | printwork = {border = '#9298A8', title = '#DDE6FF', above = '#E1E7FF', group = '#E6E9FF', subgroup = '#EAECFF', dark = '#EDF2FF', background = '#F4F9FF'}; |
| + | } |
| + | |
| + | -- function for easy adding of styles to html tags |
| + | function Utils.addStyle(tbl, val) |
| + | if Utils.isset(val) then |
| + | local av = tostring(val):gsub("^%s*(.-)%s*$", "%1") |
| + | if string.sub(av, -1) ~= ';' then av = av .. ';' end |
| + | tbl[#tbl+1] = av |
| + | end |
| end | | end |
| | | |
| return Utils | | return Utils |