Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 1: | Linia 1: | ||
+ | ---Holds the tables with the l10n information for the different languages, taken from the l10n submodule. |
||
− | -- l10n text, needs to be translated. |
||
local l10n_data = mw.loadData('Module:Exclusive/l10n') |
local l10n_data = mw.loadData('Module:Exclusive/l10n') |
||
− | -- exclusive info database, please read the documentation of Module:Exclusive/data |
||
⚫ | |||
+ | ---Database with exclusivity info. |
||
− | ------- The following is not related to l10n. -------------- |
||
⚫ | |||
− | local bit32 = require( |
+ | local bit32 = require('bit32') |
local trim = mw.text.trim |
local trim = mw.text.trim |
||
+ | ---Default content language of the wiki (i.e. `$wgLanguageCode`, not the value of the |
||
⚫ | |||
+ | ---`uselang` URL parameter, and not the user's language preference setting). |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
local contentLanguage = mw.getContentLanguage() |
local contentLanguage = mw.getContentLanguage() |
||
+ | ---Holds the arguments from the template call. |
||
⚫ | |||
+ | |||
+ | ---The current language. Determines which l10n table to use. |
||
local lang |
local lang |
||
+ | |||
⚫ | |||
+ | ---Return the l10n string associated with the `key`. |
||
+ | ---@param key string |
||
+ | ---@return string |
||
+ | local function l10n(key) |
||
if l10n_data[lang] then |
if l10n_data[lang] then |
||
return l10n_data[lang][key] or l10n_data['en'][key] |
return l10n_data[lang][key] or l10n_data['en'][key] |
||
Linia 33: | Linia 29: | ||
end |
end |
||
+ | ---Return a trimmed version of the value of the template parameter with the specified `key`. |
||
⚫ | |||
+ | ---Return `nil` if the parameter is empty or unset. |
||
− | -- helper function |
||
+ | ---@param key string|number |
||
⚫ | |||
+ | ---@return string|nil |
||
⚫ | |||
local value = trim(args_table[key] or '') |
local value = trim(args_table[key] or '') |
||
return (value ~= '') and value or nil |
return (value ~= '') and value or nil |
||
end |
end |
||
+ | ---Split the `str` on each `div` in it and return the result as a table. |
||
− | local standAndExtr = function(page) |
||
⚫ | |||
⚫ | |||
+ | ---Credit: http://richard.warburton.it. |
||
+ | ---@param div string |
||
+ | ---@param str string |
||
+ | ---@return table|boolean |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | |||
+ | ---Return the integer defined in the database for the specified `page`. |
||
+ | ---Perform some standardization on the `page` for that first. |
||
+ | ---@param page string |
||
⚫ | |||
+ | local function readFromDb(page) |
||
⚫ | |||
page = contentLanguage:ucfirst(string.gsub(string.gsub(page or '', '#.*', ''), '_', ' ')) |
page = contentLanguage:ucfirst(string.gsub(string.gsub(page or '', '#.*', ''), '_', ' ')) |
||
return exclusive_info[page] or 0 |
return exclusive_info[page] or 0 |
||
end |
end |
||
+ | ---Override the exclusivity information in `info` |
||
⚫ | |||
+ | ---with the content of `dcom3j`. |
||
⚫ | |||
+ | ---@param info number |
||
+ | ---@param dcom3j string Expected format: `<d>:<c>:<o>:<m>:<3>:<j>`, with each platform either a Boolean string ("y", "0", etc.) or an empty string |
||
+ | ---@return number |
||
⚫ | |||
⚫ | |||
if v ~= '' then |
if v ~= '' then |
||
if v == '1' or v == 'y' or v == 'yes' then |
if v == '1' or v == 'y' or v == 'yes' then |
||
Linia 57: | Linia 82: | ||
end |
end |
||
return info |
return info |
||
+ | |||
+ | -- Example to demonstrate the behavior of this function: |
||
+ | -- Goal: Change "dcom" to "dco3". |
||
+ | -- info = 15 ("dcom"), dcom3j = ":::no:yes:" |
||
+ | -- decimal 15 = binary 001111 |
||
+ | -- The first "no" is at index 3 in the dcom3j string, so |
||
+ | -- replace the corresponding bit with a 0: 001111 -> 000111. |
||
+ | -- The "yes" is at index 4, so replace the bit at index 4 |
||
+ | -- with a 1: 000111 -> 010111. |
||
+ | -- The result is info = 23 ("dco3"). |
||
end |
end |
||
+ | ---Main function to retrieve exclusivity information. |
||
⚫ | |||
+ | ---@param page string The entity to get the info about. |
||
+ | ---@param invert boolean Whether to invert the exclusivity info. |
||
+ | ---@param pagenot string The entity whose exclusivity info to subtract from the main one's. |
||
+ | ---@param dcom3j string Manual exclusivity info to override the fetched one with. |
||
+ | ---@return number info An integer that holds the exclusivity information. |
||
⚫ | |||
local info = 0 |
local info = 0 |
||
+ | |||
+ | -- A piece of exclusivity information is a set of Boolean values, one |
||
+ | -- for each platform. This is represented as bits of the `info` integer. |
||
+ | -- Each platform (Desktop, Console, Old-gen console, Mobile, 3DS, |
||
+ | -- and Japanese console – "dcom3j") is assigned one bit, in this order. |
||
+ | -- This means that, for instance, an `info` value of 1 would represent |
||
+ | -- Desktop-only exclusivity ("d"): |
||
+ | -- decimal 1 = binary 000001 |
||
+ | -- j3mocd -> "d" |
||
+ | -- Similarly, an `info` value of 20 would represent Old-gen and 3DS exclusivity ("o3"): |
||
+ | -- decimal 20 = binary 010100 |
||
+ | -- j3mocd -> "o3" |
||
+ | -- See Module:Exclusive/data for a quick overview of all values. |
||
+ | |||
+ | -- This system allows using bitwise operations (https://en.wikipedia.org/wiki/Bitwise_operation) |
||
+ | -- instead of the formerly used string processing, resulting in much lower script execution times. |
||
+ | |||
+ | |||
+ | -- get info about page |
||
if page then |
if page then |
||
− | info = |
+ | info = readFromDb(page) |
if invert then |
if invert then |
||
− | + | -- invert dcom3 and set j=0 (always force-off Japanese console when inverting) |
|
+ | info = bit32.band(bit32.bnot(info), 31) |
||
end |
end |
||
⚫ | |||
if pagenot then |
if pagenot then |
||
⚫ | |||
− | local info_not = |
+ | local info_not = readFromDb(pagenot) |
− | info = bit32.band(info, bit32.bnot(info_not)) |
+ | info = bit32.band(info, bit32.bnot(info_not)) |
end |
end |
||
+ | |||
+ | -- The "invert" and "pagenot" functionalities above utilize |
||
+ | -- bit masking (https://en.wikipedia.org/wiki/Mask_(computing)). |
||
+ | -- The following example demonstrates the operations: |
||
+ | -- 1. assume info=11 ("dcm", binary 001011) |
||
+ | -- 2. invert: |
||
+ | -- 2a. not(001011) = 110100 ("o3j", the inverse of "dcm") |
||
+ | -- 2b. and(110100, 011111) = 010100 ("o3", forced-off "j") |
||
+ | -- 3. assume info_not=4 ("o", binary 000100) |
||
+ | -- 3a. not(000100) = 111011 |
||
+ | -- 3b. and(010100, 111011) = 010000 ("3") |
||
+ | -- An initial exclusivity info of "dcm" was inverted to "o3", |
||
+ | -- then "o" was subtracted from it, resulting in the final |
||
+ | -- exclusivity information of "3". |
||
end |
end |
||
+ | |||
− | -- override if needed |
+ | -- override if needed |
if dcom3j == nil or dcom3j == ':::::' then |
if dcom3j == nil or dcom3j == ':::::' then |
||
return info |
return info |
||
Linia 80: | Linia 156: | ||
end |
end |
||
+ | ---Return an HTML span tag whose `class` attribute is set |
||
⚫ | |||
+ | ---according to the exclusivity `info`. |
||
+ | ---@param info number |
||
+ | ---@param _small boolean Whether to add the "s" class, for small icons |
||
+ | ---@return string |
||
⚫ | |||
⚫ | |||
+ | |||
if bit32.btest(info, 32) then |
if bit32.btest(info, 32) then |
||
+ | -- Japanese console is set, so simply display that |
||
⚫ | |||
+ | -- ("j" is always alone or not set at all – "dcj", for instance, doesn't exist) |
||
+ | class = class .. ' j' |
||
+ | local hovertext = l10n('text_j') |
||
⚫ | |||
end |
end |
||
+ | -- for each platform of dcom3, add the class and load the hovertext if the platform if set |
||
⚫ | |||
+ | -- (e.g. for info=25 ("dm3"), append "i0 i3 i4" to the class and load the |
||
+ | -- "text_0", "text_3", and "text_4" l10n strings) |
||
local v = {} |
local v = {} |
||
for i = 0, 4 do |
for i = 0, 4 do |
||
if bit32.btest(info, 2^i) then |
if bit32.btest(info, 2^i) then |
||
− | class = class .. ' i'..i |
+ | class = class .. ' i' .. i |
− | v[#v+1] = l10n('text_'..i) |
+ | v[#v+1] = l10n('text_' .. i) |
end |
end |
||
end |
end |
||
− | local |
+ | local hovertext = mw.text.listToText(v, l10n('list_separator'), l10n('list_conjunction')) |
+ | hovertext = hovertext .. contentLanguage:convertPlural(#v, l10n('version_plural_forms')) |
||
− | return mw.text.tag('span', {class=class |
+ | return mw.text.tag('span', {class=class}, mw.text.tag('span', {title=hovertext}, '')) |
end |
end |
||
+ | ---Check if the `infoToCheck` integer is a valid number for output. |
||
⚫ | |||
+ | ---It is considered invalid if it represents an empty exclusivity ("") |
||
+ | ---or a "full" exclusivity, i.e. all platforms being set ("dcom3" or "dcom3j"). |
||
+ | ---@param infoToCheck number |
||
+ | ---@return boolean |
||
+ | local function infoIsInvalid(infoToCheck) |
||
+ | return infoToCheck == 0 or infoToCheck == 31 or infoToCheck == 63 |
||
⚫ | |||
⚫ | |||
+ | -- main return object |
||
+ | return { |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | if infoIsInvalid(info) then |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | getInfo = function(frame) |
||
⚫ | |||
⚫ | |||
− | if info == 0 or info == 31 or info == 63 then -- dcom3 or dcom3j are also invalid. |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | if infoIsInvalid(info) then |
||
⚫ | |||
⚫ | |||
⚫ | |||
+ | end |
||
⚫ | |||
⚫ | |||
− | if info == 0 or info == 31 or info == 63 then -- dcom3 or dcom3j are also invalid. |
||
⚫ | |||
⚫ | |||
− | + | end, |
|
⚫ | |||
⚫ | |||
⚫ | |||
− | + | -- simplified version of the eicons function above, for other modules such as Module:Item |
|
− | + | simpleEicons = function(page, language, small) |
|
− | + | local info = getInfo(page) |
|
+ | if infoIsInvalid(info) then |
||
− | if info == 0 or info == 31 or info == 63 then -- dcom3 or dcom3j are invalid. |
||
− | + | return '' |
|
− | + | end |
|
− | + | lang = language -- set lang for l10n |
|
− | + | return eicons(info, small) |
|
− | + | end, |
|
} |
} |
Wersja z 12:30, 25 sie 2021
Dokumentacja Poniższa dokumentacja jest załączona do Moduł:Exclusive/opis. (edytuj | historia)
Ten moduł zarządza wszystkim co jest związane z {{exclusive}}.
Trzy wywoływane funkcje to getInfo
, ogólna funkcja wyłączności, która przechowuje informacje w dplvar, eicons
, która zapewnia funkcjonalność {{eicons}} oraz simpleEicons
, funkcja pomocnicza, która jest używana w innych modułach, takich jak Moduł:Item.
Ważna uwaga dotycząca przenoszenia
Przenosząc szablony/moduły związane z {{exclusive}} do stron wiki w oddzielnym języku, możesz nie chcieć używać systemu pamięci podręcznej opartego na ładunkach, jak na angielskiej wiki.
Wykonaj następujące czynności, aby użyć systemu pamięci podręcznej innego niż cargo:
- Nie przenoś bezpośrednio
Moduł:Exclusive/data
z en wiki. Zamiast tego przejdź do Template:Exclusive/luadata (en), skopiuj wygenerowany kod z tej strony, i umieść go jako kod źródłowyModuł:Exclusive/data
na wiki języka docelowego. Pamiętaj, że ten proces będzie musiał zostać powtórzony w przyszłości, aby aktualizować bazę danych wyłączności językowej wiki. - Upewnij się, że przełącznik automatycznego tłumaczenia l10n dla języka docelowego w
Szablon:Exclusive
/Szablon:Eil
/Szablon:Eicons
/Szablon:Eversions
jest ustawiony nafalse
(false
jest wartością domyślną dla języków innych niż angielski). - Upewnij się, że przełącznik cargo l10n dla języka docelowego w
Szablon:Exclusive
(na początku) jest ustawiony nafalse
.
---Holds the tables with the l10n information for the different languages, taken from the l10n submodule.
local l10n_data = mw.loadData('Module:Exclusive/l10n')
---Database with exclusivity info.
local exclusive_info = mw.loadData('Module:Exclusive/data')
local bit32 = require('bit32')
local trim = mw.text.trim
---Default content language of the wiki (i.e. `$wgLanguageCode`, not the value of the
---`uselang` URL parameter, and not the user's language preference setting).
local contentLanguage = mw.getContentLanguage()
---Holds the arguments from the template call.
local args_table
---The current language. Determines which l10n table to use.
local lang
---Return the l10n string associated with the `key`.
---@param key string
---@return string
local function l10n(key)
if l10n_data[lang] then
return l10n_data[lang][key] or l10n_data['en'][key]
else
return l10n_data['en'][key]
end
end
---Return a trimmed version of the value of the template parameter with the specified `key`.
---Return `nil` if the parameter is empty or unset.
---@param key string|number
---@return string|nil
local function getArg(key)
local value = trim(args_table[key] or '')
return (value ~= '') and value or nil
end
---Split the `str` on each `div` in it and return the result as a table.
---This is much much faster then `mw.text.split`.
---Credit: http://richard.warburton.it.
---@param div string
---@param str string
---@return table|boolean
local function explode(div,str)
if (div=='') then return false end
local pos,arr = 0,{}
-- for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
arr[#arr + 1] = string.sub(str,pos,st-1) -- Attach chars left of current divider
pos = sp + 1 -- Jump past current divider
end
arr[#arr + 1] = string.sub(str,pos) -- Attach chars right of last divider
return arr
end
---Return the integer defined in the database for the specified `page`.
---Perform some standardization on the `page` for that first.
---@param page string
---@return number
local function readFromDb(page)
-- standardize pagename: remove section parts ('x#section' -> 'x') and replace underscores with spaces
page = contentLanguage:ucfirst(string.gsub(string.gsub(page or '', '#.*', ''), '_', ' '))
return exclusive_info[page] or 0
end
---Override the exclusivity information in `info`
---with the content of `dcom3j`.
---@param info number
---@param dcom3j string Expected format: `<d>:<c>:<o>:<m>:<3>:<j>`, with each platform either a Boolean string ("y", "0", etc.) or an empty string
---@return number
local function override(info, dcom3j)
for k, v in pairs(explode(':', dcom3j)) do
if v ~= '' then
if v == '1' or v == 'y' or v == 'yes' then
info = bit32.replace(info, 1, k-1)
elseif v == '0' or v == 'n' or v == 'no' then
info = bit32.replace(info, 0, k-1)
end
end
end
return info
-- Example to demonstrate the behavior of this function:
-- Goal: Change "dcom" to "dco3".
-- info = 15 ("dcom"), dcom3j = ":::no:yes:"
-- decimal 15 = binary 001111
-- The first "no" is at index 3 in the dcom3j string, so
-- replace the corresponding bit with a 0: 001111 -> 000111.
-- The "yes" is at index 4, so replace the bit at index 4
-- with a 1: 000111 -> 010111.
-- The result is info = 23 ("dco3").
end
---Main function to retrieve exclusivity information.
---@param page string The entity to get the info about.
---@param invert boolean Whether to invert the exclusivity info.
---@param pagenot string The entity whose exclusivity info to subtract from the main one's.
---@param dcom3j string Manual exclusivity info to override the fetched one with.
---@return number info An integer that holds the exclusivity information.
local function getInfo(page, invert, pagenot, dcom3j)
local info = 0
-- A piece of exclusivity information is a set of Boolean values, one
-- for each platform. This is represented as bits of the `info` integer.
-- Each platform (Desktop, Console, Old-gen console, Mobile, 3DS,
-- and Japanese console – "dcom3j") is assigned one bit, in this order.
-- This means that, for instance, an `info` value of 1 would represent
-- Desktop-only exclusivity ("d"):
-- decimal 1 = binary 000001
-- j3mocd -> "d"
-- Similarly, an `info` value of 20 would represent Old-gen and 3DS exclusivity ("o3"):
-- decimal 20 = binary 010100
-- j3mocd -> "o3"
-- See Module:Exclusive/data for a quick overview of all values.
-- This system allows using bitwise operations (https://en.wikipedia.org/wiki/Bitwise_operation)
-- instead of the formerly used string processing, resulting in much lower script execution times.
-- get info about page
if page then
info = readFromDb(page)
if invert then
-- invert dcom3 and set j=0 (always force-off Japanese console when inverting)
info = bit32.band(bit32.bnot(info), 31)
end
if pagenot then
-- exclude some versions, depending on pagenot
local info_not = readFromDb(pagenot)
info = bit32.band(info, bit32.bnot(info_not))
end
-- The "invert" and "pagenot" functionalities above utilize
-- bit masking (https://en.wikipedia.org/wiki/Mask_(computing)).
-- The following example demonstrates the operations:
-- 1. assume info=11 ("dcm", binary 001011)
-- 2. invert:
-- 2a. not(001011) = 110100 ("o3j", the inverse of "dcm")
-- 2b. and(110100, 011111) = 010100 ("o3", forced-off "j")
-- 3. assume info_not=4 ("o", binary 000100)
-- 3a. not(000100) = 111011
-- 3b. and(010100, 111011) = 010000 ("3")
-- An initial exclusivity info of "dcm" was inverted to "o3",
-- then "o" was subtracted from it, resulting in the final
-- exclusivity information of "3".
end
-- override if needed
if dcom3j == nil or dcom3j == ':::::' then
return info
else
return override(info, dcom3j)
end
end
---Return an HTML span tag whose `class` attribute is set
---according to the exclusivity `info`.
---@param info number
---@param _small boolean Whether to add the "s" class, for small icons
---@return string
local function eicons(info, _small)
local class = 'eico' .. (_small and ' s' or '')
if bit32.btest(info, 32) then
-- Japanese console is set, so simply display that
-- ("j" is always alone or not set at all – "dcj", for instance, doesn't exist)
class = class .. ' j'
local hovertext = l10n('text_j')
return mw.text.tag('span', {class=class}, mw.text.tag('span', {title=hovertext}, ''))
end
-- for each platform of dcom3, add the class and load the hovertext if the platform if set
-- (e.g. for info=25 ("dm3"), append "i0 i3 i4" to the class and load the
-- "text_0", "text_3", and "text_4" l10n strings)
local v = {}
for i = 0, 4 do
if bit32.btest(info, 2^i) then
class = class .. ' i' .. i
v[#v+1] = l10n('text_' .. i)
end
end
local hovertext = mw.text.listToText(v, l10n('list_separator'), l10n('list_conjunction'))
hovertext = hovertext .. contentLanguage:convertPlural(#v, l10n('version_plural_forms'))
return mw.text.tag('span', {class=class}, mw.text.tag('span', {title=hovertext}, ''))
end
---Check if the `infoToCheck` integer is a valid number for output.
---It is considered invalid if it represents an empty exclusivity ("")
---or a "full" exclusivity, i.e. all platforms being set ("dcom3" or "dcom3j").
---@param infoToCheck number
---@return boolean
local function infoIsInvalid(infoToCheck)
return infoToCheck == 0 or infoToCheck == 31 or infoToCheck == 63
end
-----------------------------------------------------------------
-- main return object
return {
-- for templates; get all exclusive info and set it in dplvars.
-- parameters: $1 = pagename
getInfo = function(frame)
args_table = frame.args -- cache
local info = getInfo(getArg(1), getArg('invert'), getArg('pagenot'))
if infoIsInvalid(info) then
frame:callParserFunction{ name = '#dplvar:set', args = {
'ex_d', '',
'ex_c', '',
'ex_o', '',
'ex_m', '',
'ex_3', '',
'ex_j', '',
'ex_cached', 'y'
} }
else
frame:callParserFunction{ name = '#dplvar:set', args = {
'ex_d', bit32.btest(info, 2^0) and 'y' or '',
'ex_c', bit32.btest(info, 2^1) and 'y' or '',
'ex_o', bit32.btest(info, 2^2) and 'y' or '',
'ex_m', bit32.btest(info, 2^3) and 'y' or '',
'ex_3', bit32.btest(info, 2^4) and 'y' or '',
'ex_j', bit32.btest(info, 2^5) and 'y' or '',
'ex_cached', 'y'
} }
end
end,
-- for {{eicons}}
eicons = function(frame)
args_table = frame.args -- cache
local info = getInfo(getArg(1), getArg('invert'), getArg('pagenot'), getArg('dcom3j'))
if infoIsInvalid(info) then
return frame:expandTemplate{ title = 'error', args = { l10n('eicons_error_text'), l10n('eicons_error_cate'), from = 'Eicons' } }
end
lang = getArg('lang') -- set lang for l10n
return eicons(info, getArg('small'))
end,
-- simplified version of the eicons function above, for other modules such as Module:Item
simpleEicons = function(page, language, small)
local info = getInfo(page)
if infoIsInvalid(info) then
return ''
end
lang = language -- set lang for l10n
return eicons(info, small)
end,
}