Модуль:Common

Материал из Touhou Wiki
Перейти к навигации Перейти к поиску

Для документации этого модуля может быть создана страница Модуль:Common/doc

--[[
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