|
|
| (4 intermediate revisions by 2 users not shown) |
| Line 1: |
Line 1: |
| -- Original module located at [[:en:Module:Wd]] and [[:en:Module:Wd/i18n]].
| |
|
| |
|
| local p = {}
| |
| local arg = ...
| |
| local i18n
| |
|
| |
| local function loadI18n(aliasesP, frame)
| |
| local title
| |
|
| |
| if frame then
| |
| -- current module invoked by page/template, get its title from frame
| |
| title = frame:getTitle()
| |
| else
| |
| -- current module included by other module, get its title from ...
| |
| title = arg
| |
| end
| |
|
| |
| if not i18n then
| |
| i18n = require(title .. "/i18n").init(aliasesP)
| |
| end
| |
| end
| |
|
| |
| p.claimCommands = {
| |
| property = "property",
| |
| properties = "properties",
| |
| qualifier = "qualifier",
| |
| qualifiers = "qualifiers",
| |
| reference = "reference",
| |
| references = "references"
| |
| }
| |
|
| |
| p.generalCommands = {
| |
| label = "label",
| |
| title = "title",
| |
| description = "description",
| |
| alias = "alias",
| |
| aliases = "aliases",
| |
| badge = "badge",
| |
| badges = "badges"
| |
| }
| |
|
| |
| p.flags = {
| |
| linked = "linked",
| |
| short = "short",
| |
| raw = "raw",
| |
| multilanguage = "multilanguage",
| |
| unit = "unit",
| |
| -------------
| |
| preferred = "preferred",
| |
| normal = "normal",
| |
| deprecated = "deprecated",
| |
| best = "best",
| |
| future = "future",
| |
| current = "current",
| |
| former = "former",
| |
| edit = "edit",
| |
| editAtEnd = "edit@end",
| |
| mdy = "mdy",
| |
| single = "single",
| |
| sourced = "sourced"
| |
| }
| |
|
| |
| p.args = {
| |
| eid = "eid",
| |
| page = "page",
| |
| date = "date"
| |
| }
| |
|
| |
| local aliasesP = {
| |
| coord = "P625",
| |
| -----------------------
| |
| image = "P18",
| |
| author = "P50",
| |
| publisher = "P123",
| |
| importedFrom = "P143",
| |
| statedIn = "P248",
| |
| pages = "P304",
| |
| language = "P407",
| |
| hasPart = "P527",
| |
| publicationDate = "P577",
| |
| startTime = "P580",
| |
| endTime = "P582",
| |
| chapter = "P792",
| |
| retrieved = "P813",
| |
| referenceURL = "P854",
| |
| sectionVerseOrParagraph = "P958",
| |
| archiveURL = "P1065",
| |
| title = "P1476",
| |
| formatterURL = "P1630",
| |
| quote = "P1683",
| |
| shortName = "P1813",
| |
| definingFormula = "P2534",
| |
| archiveDate = "P2960",
| |
| inferredFrom = "P3452",
| |
| typeOfReference = "P3865",
| |
| column = "P3903"
| |
| }
| |
|
| |
| local aliasesQ = {
| |
| percentage = "Q11229",
| |
| prolepticJulianCalendar = "Q1985786",
| |
| citeWeb = "Q5637226",
| |
| citeQ = "Q22321052"
| |
| }
| |
|
| |
| local parameters = {
| |
| property = "%p",
| |
| qualifier = "%q",
| |
| reference = "%r",
| |
| alias = "%a",
| |
| badge = "%b",
| |
| separator = "%s",
| |
| general = "%x"
| |
| }
| |
|
| |
| local formats = {
| |
| property = "%p[%s][%r]",
| |
| qualifier = "%q[%s][%r]",
| |
| reference = "%r",
| |
| propertyWithQualifier = "%p[ <span style=\"font-size:85\\%\">(%q)</span>][%s][%r]",
| |
| alias = "%a[%s]",
| |
| badge = "%b[%s]"
| |
| }
| |
|
| |
| local hookNames = { -- {level_1, level_2}
| |
| [parameters.property] = {"getProperty"},
| |
| [parameters.reference] = {"getReferences", "getReference"},
| |
| [parameters.qualifier] = {"getAllQualifiers"},
| |
| [parameters.qualifier.."\\d"] = {"getQualifiers", "getQualifier"},
| |
| [parameters.alias] = {"getAlias"},
| |
| [parameters.badge] = {"getBadge"}
| |
| }
| |
|
| |
| -- default value objects, should NOT be mutated but instead copied
| |
| local defaultSeparators = {
| |
| ["sep"] = {" "},
| |
| ["sep%s"] = {","},
| |
| ["sep%q"] = {"; "},
| |
| ["sep%q\\d"] = {", "},
| |
| ["sep%r"] = nil, -- none
| |
| ["punc"] = nil -- none
| |
| }
| |
|
| |
| local rankTable = {
| |
| ["preferred"] = 1,
| |
| ["normal"] = 2,
| |
| ["deprecated"] = 3
| |
| }
| |
|
| |
| local Config = {}
| |
|
| |
| -- allows for recursive calls
| |
| function Config:new()
| |
| local cfg = {}
| |
| setmetatable(cfg, self)
| |
| self.__index = self
| |
|
| |
| cfg.separators = {
| |
| -- single value objects wrapped in arrays so that we can pass by reference
| |
| ["sep"] = {copyTable(defaultSeparators["sep"])},
| |
| ["sep%s"] = {copyTable(defaultSeparators["sep%s"])},
| |
| ["sep%q"] = {copyTable(defaultSeparators["sep%q"])},
| |
| ["sep%r"] = {copyTable(defaultSeparators["sep%r"])},
| |
| ["punc"] = {copyTable(defaultSeparators["punc"])}
| |
| }
| |
|
| |
| cfg.entity = nil
| |
| cfg.entityID = nil
| |
| cfg.propertyID = nil
| |
| cfg.propertyValue = nil
| |
| cfg.qualifierIDs = {}
| |
| cfg.qualifierIDsAndValues = {}
| |
|
| |
| cfg.bestRank = true
| |
| cfg.ranks = {true, true, false} -- preferred = true, normal = true, deprecated = false
| |
| cfg.foundRank = #cfg.ranks
| |
| cfg.flagBest = false
| |
| cfg.flagRank = false
| |
|
| |
| cfg.periods = {true, true, true} -- future = true, current = true, former = true
| |
| cfg.flagPeriod = false
| |
| cfg.atDate = {parseDate(os.date('!%Y-%m-%d'))} -- today as {year, month, day}
| |
|
| |
| cfg.mdyDate = false
| |
| cfg.singleClaim = false
| |
| cfg.sourcedOnly = false
| |
| cfg.editable = false
| |
| cfg.editAtEnd = false
| |
|
| |
| cfg.inSitelinks = false
| |
|
| |
| cfg.langCode = mw.language.getContentLanguage().code
| |
| cfg.langName = mw.language.fetchLanguageName(cfg.langCode, cfg.langCode)
| |
| cfg.langObj = mw.language.new(cfg.langCode)
| |
|
| |
| cfg.siteID = mw.wikibase.getGlobalSiteId()
| |
|
| |
| cfg.states = {}
| |
| cfg.states.qualifiersCount = 0
| |
| cfg.curState = nil
| |
|
| |
| cfg.prefetchedRefs = nil
| |
|
| |
| return cfg
| |
| end
| |
|
| |
| local State = {}
| |
|
| |
| function State:new(cfg, type)
| |
| local stt = {}
| |
| setmetatable(stt, self)
| |
| self.__index = self
| |
|
| |
| stt.conf = cfg
| |
| stt.type = type
| |
|
| |
| stt.results = {}
| |
|
| |
| stt.parsedFormat = {}
| |
| stt.separator = {}
| |
| stt.movSeparator = {}
| |
| stt.puncMark = {}
| |
|
| |
| stt.linked = false
| |
| stt.rawValue = false
| |
| stt.shortName = false
| |
| stt.anyLanguage = false
| |
| stt.unitOnly = false
| |
| stt.singleValue = false
| |
|
| |
| return stt
| |
| end
| |
|
| |
| local function replaceAlias(id)
| |
| if aliasesP[id] then
| |
| id = aliasesP[id]
| |
| end
| |
|
| |
| return id
| |
| end
| |
|
| |
| local function errorText(code, param)
| |
| local text = i18n["errors"][code]
| |
| if param then text = mw.ustring.gsub(text, "$1", param) end
| |
| return text
| |
| end
| |
|
| |
| local function throwError(errorMessage, param)
| |
| error(errorText(errorMessage, param))
| |
| end
| |
|
| |
| local function replaceDecimalMark(num)
| |
| return mw.ustring.gsub(num, "[.]", i18n['numeric']['decimal-mark'], 1)
| |
| end
| |
|
| |
| local function padZeros(num, numDigits)
| |
| local numZeros
| |
| local negative = false
| |
|
| |
| if num < 0 then
| |
| negative = true
| |
| num = num * -1
| |
| end
| |
|
| |
| num = tostring(num)
| |
| numZeros = numDigits - num:len()
| |
|
| |
| for _ = 1, numZeros do
| |
| num = "0"..num
| |
| end
| |
|
| |
| if negative then
| |
| num = "-"..num
| |
| end
| |
|
| |
| return num
| |
| end
| |
|
| |
| local function replaceSpecialChar(chr)
| |
| if chr == '_' then
| |
| -- replace underscores with spaces
| |
| return ' '
| |
| else
| |
| return chr
| |
| end
| |
| end
| |
|
| |
| local function replaceSpecialChars(str)
| |
| local chr
| |
| local esc = false
| |
| local strOut = ""
| |
|
| |
| for i = 1, #str do
| |
| chr = str:sub(i,i)
| |
|
| |
| if not esc then
| |
| if chr == '\\' then
| |
| esc = true
| |
| else
| |
| strOut = strOut .. replaceSpecialChar(chr)
| |
| end
| |
| else
| |
| strOut = strOut .. chr
| |
| esc = false
| |
| end
| |
| end
| |
|
| |
| return strOut
| |
| end
| |
|
| |
| local function buildWikilink(target, label)
| |
| if not label or target == label then
| |
| return "[[" .. target .. "]]"
| |
| else
| |
| return "[[" .. target .. "|" .. label .. "]]"
| |
| end
| |
| end
| |
|
| |
| -- used to make frame.args mutable, to replace #frame.args (which is always 0)
| |
| -- with the actual amount and to simply copy tables
| |
| function copyTable(tIn)
| |
| if not tIn then
| |
| return nil
| |
| end
| |
|
| |
| local tOut = {}
| |
|
| |
| for i, v in pairs(tIn) do
| |
| tOut[i] = v
| |
| end
| |
|
| |
| return tOut
| |
| end
| |
|
| |
| -- used to merge output arrays together;
| |
| -- note that it currently mutates the first input array
| |
| local function mergeArrays(a1, a2)
| |
| for i = 1, #a2 do
| |
| a1[#a1 + 1] = a2[i]
| |
| end
| |
|
| |
| return a1
| |
| end
| |
|
| |
| local function split(str, del)
| |
| local out = {}
| |
| local i, j = str:find(del)
| |
|
| |
| if i and j then
| |
| out[1] = str:sub(1, i - 1)
| |
| out[2] = str:sub(j + 1)
| |
| else
| |
| out[1] = str
| |
| end
| |
|
| |
| return out
| |
| end
| |
|
| |
| local function parseWikidataURL(url)
| |
| local id
| |
|
| |
| if url:match('^http[s]?://') then
| |
| id = split(url, "Q")
| |
|
| |
| if id[2] then
| |
| return "Q" .. id[2]
| |
| end
| |
| end
| |
|
| |
| return nil
| |
| end
| |
|
| |
| function parseDate(dateStr, precision)
| |
| precision = precision or "d"
| |
|
| |
| local i, j, index, ptr
| |
| local parts = {nil, nil, nil}
| |
|
| |
| if dateStr == nil then
| |
| return parts[1], parts[2], parts[3] -- year, month, day
| |
| end
| |
|
| |
| -- 'T' for snak values, '/' for outputs with '/Julian' attached
| |
| i, j = dateStr:find("[T/]")
| |
|
| |
| if i then
| |
| dateStr = dateStr:sub(1, i-1)
| |
| end
| |
|
| |
| local from = 1
| |
|
| |
| if dateStr:sub(1,1) == "-" then
| |
| -- this is a negative number, look further ahead
| |
| from = 2
| |
| end
| |
|
| |
| index = 1
| |
| ptr = 1
| |
|
| |
| i, j = dateStr:find("-", from)
| |
|
| |
| if i then
| |
| -- year
| |
| parts[index] = tonumber(mw.ustring.gsub(dateStr:sub(ptr, i-1), "^\+(.+)$", "%1"), 10) -- remove '+' sign (explicitly give base 10 to prevent error)
| |
|
| |
| if parts[index] == -0 then
| |
| parts[index] = tonumber("0") -- for some reason, 'parts[index] = 0' may actually store '-0', so parse from string instead
| |
| end
| |
|
| |
| if precision == "y" then
| |
| -- we're done
| |
| return parts[1], parts[2], parts[3] -- year, month, day
| |
| end
| |
|
| |
| index = index + 1
| |
| ptr = i + 1
| |
|
| |
| i, j = dateStr:find("-", ptr)
| |
|
| |
| if i then
| |
| -- month
| |
| parts[index] = tonumber(dateStr:sub(ptr, i-1), 10)
| |
|
| |
| if precision == "m" then
| |
| -- we're done
| |
| return parts[1], parts[2], parts[3] -- year, month, day
| |
| end
| |
|
| |
| index = index + 1
| |
| ptr = i + 1
| |
| end
| |
| end
| |
|
| |
| if dateStr:sub(ptr) ~= "" then
| |
| -- day if we have month, month if we have year, or year
| |
| parts[index] = tonumber(dateStr:sub(ptr), 10)
| |
| end
| |
|
| |
| return parts[1], parts[2], parts[3] -- year, month, day
| |
| end
| |
|
| |
| local function datePrecedesDate(aY, aM, aD, bY, bM, bD)
| |
| if aY == nil or bY == nil then
| |
| return nil
| |
| end
| |
| aM = aM or 1
| |
| aD = aD or 1
| |
| bM = bM or 1
| |
| bD = bD or 1
| |
|
| |
| if aY < bY then
| |
| return true
| |
|