en:Module:Wd 2017年3月18日 (土) 20:02(UTC)より
template>K-iczn (en:Module:Wd 2017年2月10日 (金) 11:09(UTC)より) |
template>K-iczn (en:Module:Wd 2017年3月18日 (土) 20:02(UTC)より) |
||
3行目: | 3行目: | ||
local aliasesP = { | local aliasesP = { | ||
coord = "P625", | coord = "P625", | ||
author = "P50", | author = "P50", | ||
publisher = "P123", | publisher = "P123", | ||
29行目: | 30行目: | ||
qualifier = "%q", | qualifier = "%q", | ||
reference = "%r", | reference = "%r", | ||
separator = "%s" | separator = "%s", | ||
general = "%x" | |||
} | } | ||
39行目: | 41行目: | ||
} | } | ||
local hookNames = { | local hookNames = { -- {level_1, level_2} | ||
[parameters.property] = {"getProperty"}, | |||
[parameters.property] | [parameters.reference] = {"getReferences", "getReference"}, | ||
[parameters. | [parameters.qualifier] = {"getAllQualifiers"}, | ||
[parameters. | [parameters.qualifier.."\\d"] = {"getQualifiers", "getQualifier"} | ||
} | |||
local defaultSeparators = { | |||
["sep"] = " " , | |||
["sep%s"] = "," , | |||
["sep%q"] = "; " , | |||
["sep%q\\d"] = ", " , | |||
["sep%r"] = "" , | |||
["punc"] = "" | |||
} | } | ||
56行目: | 67行目: | ||
cfg.separators = { | cfg.separators = { | ||
-- use tables so that we can pass by reference | -- use tables so that we can pass by reference | ||
["sep"] | ["sep"] = {defaultSeparators["sep"]}, | ||
["sep%s"] = {" | ["sep%s"] = {defaultSeparators["sep%s"]}, | ||
["sep%q"] = {" | ["sep%q"] = {defaultSeparators["sep%q"]}, | ||
["sep%r"] = {""}, | ["sep%r"] = {defaultSeparators["sep%r"]}, | ||
["punc"] = {""} | ["punc"] = {defaultSeparators["punc"]} | ||
} | } | ||
66行目: | 77行目: | ||
cfg.propertyID = nil | cfg.propertyID = nil | ||
cfg.propertyValue = nil | cfg.propertyValue = nil | ||
cfg. | cfg.qualifierIDs = {} | ||
cfg.bestRank = true | cfg.bestRank = true | ||
86行目: | 97行目: | ||
cfg.states = {} | cfg.states = {} | ||
cfg.states.qualifiersCount = 0 | |||
cfg.curState = nil | cfg.curState = nil | ||
127行目: | 139行目: | ||
function extraRequiredParameterError(param) | function extraRequiredParameterError(param) | ||
return "パラメータ「" .. param .. "」は任意として定義する必要があります。" | return "パラメータ「" .. param .. "」は任意として定義する必要があります。" | ||
end | |||
-- used to make frame.args mutable and to replace #frame.args (which is always 0) with the actual amount | |||
function copyTable(tIn) | |||
local tOut = {} | |||
for i, v in pairs(tIn) do | |||
tOut[i] = v | |||
end | |||
return tOut | |||
end | |||
-- used to merge output tables together; | |||
-- note that it currently mutates the first input table | |||
function mergeTables(t1, t2) | |||
for i = 1, #t2 do | |||
t1[#t1 + 1] = t2[i] | |||
end | |||
return t1 | |||
end | |||
-- used to create the final output string when it's all done, | |||
-- so that extensionTag("ref") is only called when it's really in the final output | |||
function concatValues(valuesArray) | |||
local outString = "" | |||
for i = 1, #valuesArray do | |||
if valuesArray[i].refHash then | |||
-- add <ref> tag with the reference's hash as its name (to deduplicate references) | |||
outString = outString .. mw.getCurrentFrame():extensionTag("ref", valuesArray[i][1], {name = "wikidata-" .. valuesArray[i].refHash}) | |||
else | |||
outString = outString .. valuesArray[i][1] | |||
end | |||
end | |||
return outString | |||
end | |||
function getHookName(param, index) | |||
if hookNames[param] then | |||
return hookNames[param][index] | |||
elseif string.len(param) > 2 then | |||
return hookNames[string.sub(param, 1, 2).."\\d"][index] | |||
else | |||
return nil | |||
end | |||
end | end | ||
320行目: | 380行目: | ||
end | end | ||
-- The following function parses a format string. | |||
-- | |||
-- The example below shows how a parsed string is structured in memory. | |||
-- Variables other than 'str' and 'child' are left out for clarity's sake. | |||
-- | |||
-- Example: | |||
-- "A %p B [%s[%q1]] C [%r] D" | |||
-- | |||
-- Structure: | |||
-- [ | |||
-- { | |||
-- str = "A " | |||
-- }, | |||
-- { | |||
-- str = "%p" | |||
-- }, | |||
-- { | |||
-- str = " B ", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%s", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%q1" | |||
-- } | |||
-- ] | |||
-- } | |||
-- ] | |||
-- }, | |||
-- { | |||
-- str = " C ", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%r" | |||
-- } | |||
-- ] | |||
-- }, | |||
-- { | |||
-- str = " D" | |||
-- } | |||
-- ] | |||
-- | |||
function parseFormat(str) | function parseFormat(str) | ||
local chr, esc, param, root, cur | local chr, esc, param, root, cur, prev, new | ||
local params = {} | local params = {} | ||
334行目: | 439行目: | ||
end | end | ||
root = {} -- array | local function endParam() | ||
if param > 0 then | |||
if cur.str ~= "" then | |||
cur.str = "%"..cur.str | |||
cur.param = true | |||
params[cur.str] = true | |||
cur.parent.req[cur.str] = true | |||
prev = cur | |||
cur = newObject(cur.parent) | |||
end | |||
param = 0 | |||
end | |||
end | |||
root = {} -- array | |||
root.req = {} | root.req = {} | ||
cur = newObject(root) | cur = newObject(root) | ||
prev = nil | |||
esc = false | esc = false | ||
param = | param = 0 | ||
for i = 1, #str do | for i = 1, #str do | ||
346行目: | 466行目: | ||
if not esc then | if not esc then | ||
if chr == '\\' then | if chr == '\\' then | ||
endParam() | |||
esc = true | esc = true | ||
elseif chr == '%' then | elseif chr == '%' then | ||
cur = newObject(cur.parent) | endParam() | ||
param = | if cur.str ~= "" then | ||
cur = newObject(cur.parent) | |||
end | |||
param = 2 | |||
elseif chr == '[' then | |||
endParam() | |||
if prev and cur.str == "" then | |||
table.remove(cur.parent) | |||
cur = prev | |||
end | |||
cur.child = {} -- new array | |||
cur.child.req = {} | |||
cur.child.parent = cur | |||
cur = newObject(cur.child) | |||
elseif chr == ']' then | |||
endParam() | |||
if cur.parent.parent then | |||
new = newObject(cur.parent.parent.parent) | |||
if cur.str == "" then | |||
table.remove(cur.parent) | |||
end | |||
cur = new | |||
end | |||
else | else | ||
if | if param > 1 then | ||
param = param - 1 | |||
elseif param == 1 then | |||
if not string.match(chr, '%d') then | |||
endParam() | |||
elseif | |||
if | |||
end | end | ||
end | end | ||
cur.str = cur.str .. chr | |||
end | end | ||
else | else | ||
cur.str = cur.str .. chr | cur.str = cur.str .. chr | ||
esc = false | esc = false | ||
end | end | ||
prev = nil | |||
end | end | ||
endParam() | |||
return root, params | return root, params | ||
end | end | ||
function getShortName(itemID) | -- sorts the claims based on ranks, which is done to increase performance in certain cases; | ||
-- e.g. with flags "normal+|best" given and claims stored in order "normal, normal, preferred", | |||
-- then the "normal" claims would be fully processed first while the "preferred" one might be the only one returned; | |||
-- after sorting, this would be "preferred, normal, normal" and the "normal" claims won't be processed | |||
function sortOnRank(claims) | |||
local rankPos | |||
local ranks = {{}, {}, {}} -- preferred, normal, deprecated | |||
local sorted = {} | |||
for i, v in ipairs(claims) do | |||
rankPos = convertRank(v.rank) | |||
ranks[rankPos][#ranks[rankPos] + 1] = v | |||
end | |||
sorted = ranks[1] | |||
sorted = mergeTables(sorted, ranks[2]) | |||
sorted = mergeTables(sorted, ranks[3]) | |||
return sorted | |||
end | |||
function getShortName(itemID) | |||
return p._property({itemID, aliasesP.shortName}) -- "property" is single | return p._property({itemID, aliasesP.shortName}) -- "property" is single | ||
end | end | ||
469行目: | 615行目: | ||
if not raw then | if not raw then | ||
if precision == 6 then | if precision == 6 then | ||
suffix = " | suffix = "千年" | ||
else | else | ||
suffix = " | suffix = "世紀" | ||
end | end | ||
769行目: | 915行目: | ||
return value | return value | ||
else | else | ||
return '<strong class="error">' .. unknownDataTypeError(snak.datavalue.type) .. '</strong>' | return '<strong class="error">' .. unknownDataTypeError(snak.datavalue.type) .. '.</strong>' | ||
end | end | ||
elseif snak.snaktype == 'somevalue' then | elseif snak.snaktype == 'somevalue' then | ||
920行目: | 1,066行目: | ||
param = parameters.property | param = parameters.property | ||
elseif flag:match('^qualifier[s]?$') then | elseif flag:match('^qualifier[s]?$') then | ||
param = parameters.qualifier | self.states.qualifiersCount = self.states.qualifiersCount + 1 | ||
param = parameters.qualifier .. self.states.qualifiersCount | |||
self.separators["sep"..param] = {defaultSeparators["sep%q\\d"]} | |||
elseif flag:match('^reference[s]?$') then | elseif flag:match('^reference[s]?$') then | ||
param = parameters.reference | param = parameters.reference | ||
935行目: | 1,083行目: | ||
-- use "%x" as the general parameter name | -- use "%x" as the general parameter name | ||
self.states[param].parsedFormat = parseFormat( | self.states[param].parsedFormat = parseFormat(parameters.general) -- will be overwritten for param=="%p" | ||
-- set the separator | -- set the separator | ||
1,008行目: | 1,156行目: | ||
if (startTimeY == nil or not datePrecedesDate(now['year'], now['month'], now['day'], startTimeY, startTimeM, startTimeD)) and | if (startTimeY == nil or not datePrecedesDate(now['year'], now['month'], now['day'], startTimeY, startTimeM, startTimeD)) and | ||
(endTimeY == nil or datePrecedesDate(now['year'], now['month'], now['day'], endTimeY, endTimeM, endTimeD)) then | (endTimeY == nil or datePrecedesDate(now['year'], now['month'], now['day'], endTimeY, endTimeM, endTimeD)) then | ||
return true | |||
end | end | ||
end | end | ||
1,089行目: | 1,237行目: | ||
function State:out() | function State:out() | ||
local out = | local out = {} -- array with value objects | ||
local function walk(formatTable, result) | local function walk(formatTable, result) | ||
local | local valuesArray = {} -- array with value objects | ||
for i, v in pairs(formatTable.req) do | for i, v in pairs(formatTable.req) do | ||
if not result[i] then | if not result[i] or not result[i][1] then | ||
-- we've got no result for a parameter that is required on this level, | -- we've got no result for a parameter that is required on this level, | ||
-- so skip this level (and its children) by returning an empty | -- so skip this level (and its children) by returning an empty result | ||
return | return {} | ||
end | end | ||
end | end | ||
1,104行目: | 1,252行目: | ||
for i, v in ipairs(formatTable) do | for i, v in ipairs(formatTable) do | ||
if v.param then | if v.param then | ||
valuesArray = mergeTables(valuesArray, result[v.str]) | |||
else | else | ||
valuesArray[#valuesArray + 1] = {v.str} | |||
end | end | ||
if v.child then | if v.child then | ||
valuesArray = mergeTables(valuesArray, walk(v.child, result)) | |||
end | end | ||
end | end | ||
return | return valuesArray | ||
end | end | ||
local function prepend(results) | local function prepend(results) | ||
local sep = "" | local sep = "" | ||
local result | local result -- collection of arrays with value objects | ||
local valuesArray -- array with value objects | |||
-- iterate from back to front, so that we know when to add separators | -- iterate from back to front, so that we know when to add separators | ||
1,126行目: | 1,275行目: | ||
-- if there is already some output, then add the separators | -- if there is already some output, then add the separators | ||
if out | if #out > 0 then | ||
sep = self.separator[1] -- fixed separator | sep = self.separator[1] -- fixed separator | ||
result[parameters.separator] = self.movSeparator[1] -- movable separator | result[parameters.separator] = { {self.movSeparator[1]} } -- movable separator | ||
else | else | ||
sep = "" | sep = "" | ||
result[parameters.separator] = self.puncMark[1] -- optional punctuation mark | result[parameters.separator] = { {self.puncMark[1]} } -- optional punctuation mark | ||
end | end | ||
valuesArray = walk(self.parsedFormat, result) | |||
if | if #valuesArray > 0 then | ||
out = | valuesArray[#valuesArray + 1] = {sep} | ||
out = mergeTables(valuesArray, out) | |||
end | end | ||
end | end | ||
1,156行目: | 1,306行目: | ||
-- level 1 hook | -- level 1 hook | ||
function State:getProperty(claim) | function State:getProperty(claim) | ||
local value = {self.conf:getValue(claim.mainsnak, self.rawValue, self.linked, self.shortName)} -- create one value object | |||
if #value > 0 then | |||
return {value} -- wrap the value object in an array and return it | |||
else | |||
return {} -- return empty array if there was no value | |||
end | |||
end | end | ||
-- level 1 hook | -- level 1 hook | ||
function State:getQualifiers(claim) | function State:getQualifiers(claim, param) | ||
local qualifiers | local qualifiers | ||
if claim.qualifiers then qualifiers = claim.qualifiers[self.conf. | if claim.qualifiers then qualifiers = claim.qualifiers[self.conf.qualifierIDs[param]] end | ||
if qualifiers then | if qualifiers then | ||
-- iterate through claim's qualifier statements to collect their values | -- iterate through claim's qualifier statements to collect their values; | ||
return self.conf.states[ | -- return array with multiple value objects | ||
return self.conf.states[param]:iterate(qualifiers, {[parameters.general] = hookNames[parameters.qualifier.."\\d"][2], count = 1}) -- pass qualifier State with level 2 hook | |||
else | else | ||
return | return {} -- return empty array | ||
end | end | ||
end | end | ||
1,174行目: | 1,331行目: | ||
-- level 2 hook | -- level 2 hook | ||
function State:getQualifier(snak) | function State:getQualifier(snak) | ||
local value = {self.conf:getValue(snak, self.rawValue, self.linked, self.shortName)} -- create one value object | |||
if #value > 0 then | |||
-- | return {value} -- wrap the value object in an array and return it | ||
if | |||
return | |||
else | else | ||
return | return {} -- return empty array if there was no value | ||
end | end | ||
end | end | ||
-- level 2 hook | -- level 1 hook | ||
-- logic determined based on https://www.wikidata.org/wiki/Help:Sources | function State:getAllQualifiers(claim, param, result, hooks) | ||
function State:getReference(statement) | local out = {} -- array with value objects | ||
local sep = self.conf.separators["sep"..parameters.qualifier][1] | |||
-- iterate through the output of the separate "qualifier(s)" commands | |||
for i = 1, self.conf.states.qualifiersCount do | |||
-- if a hook has not been called yet, call it now | |||
if not result[parameters.qualifier..i] then | |||
self:callHook(parameters.qualifier..i, hooks, claim, result) | |||
end | |||
-- if there is output for this particular "qualifier(s)" command, then add it | |||
if result[parameters.qualifier..i] and result[parameters.qualifier..i][1] then | |||
-- if there is already some output, then add the separator | |||
if #out > 0 then | |||
out[#out + 1] = {sep} | |||
end | |||
out = mergeTables(out, result[parameters.qualifier..i]) | |||
end | |||
end | |||
return out | |||
end | |||
-- level 1 hook | |||
function State:getReferences(claim) | |||
if claim.references then | |||
-- iterate through claim's reference statements to collect their values; | |||
-- return array with multiple value objects | |||
return self.conf.states[parameters.reference]:iterate(claim.references, {[parameters.general] = hookNames[parameters.reference][2], count = 1}) -- pass reference State with level 2 hook | |||
else | |||
return {} -- return empty array | |||
end | |||
end | |||
-- level 2 hook | |||
-- logic determined based on https://www.wikidata.org/wiki/Help:Sources | |||
function State:getReference(statement) | |||
local snakValue, lang, property | local snakValue, lang, property | ||
local value = "" | local value = "" | ||
local ref = {} | |||
local snaks = {} | local snaks = {} | ||
local params = {} | local params = {} | ||
1,263行目: | 1,456行目: | ||
if value ~= "" then | if value ~= "" then | ||
ref = {value} -- create one value object | |||
if not self.rawValue then | if not self.rawValue then | ||
-- | -- this should become a <ref> tag, so safe the reference's hash for later | ||
ref.refHash = statement.hash | |||
end | end | ||
value | ref = {ref} -- wrap the value object in an array | ||
end | end | ||
end | end | ||
return | return ref | ||
end | end | ||
-- iterate through claims, claim's qualifiers or claim's references to collect values | function State:callHook(param, hooks, statement, result) | ||
function State:iterate(statements, hooks, matchHook) | local valuesArray, refHash | ||
matchHook = matchHook or alwaysTrue | |||
-- call a parameter's hook if it has been defined and if it has not been called before | |||
if not result[param] and hooks[param] then | |||
valuesArray = self[hooks[param]](self, statement, param, result, hooks) -- array with value objects | |||
-- add to the result | |||
if #valuesArray > 0 then | |||
result[param] = valuesArray | |||
result.count = result.count + 1 | |||
else | |||
result[param] = {} -- an empty array to indicate that we've tried this hook already | |||
return true -- miss == true | |||
end | |||
end | |||
return false | |||
end | |||
-- iterate through claims, claim's qualifiers or claim's references to collect values | |||
function State:iterate(statements, hooks, matchHook) | |||
matchHook = matchHook or alwaysTrue | |||
local done = false | local done = false | ||
1,290行目: | 1,505行目: | ||
if matches then | if matches then | ||
result = {count = 0} | result = {count = 0} -- collection of arrays with value objects | ||
doAppend = true | doAppend = true | ||
1,310行目: | 1,525行目: | ||
if doAppend then | if doAppend then | ||
local function walk(formatTable) | local function walk(formatTable) | ||
local | local miss | ||
for i2, v2 in pairs(formatTable.req) do | for i2, v2 in pairs(formatTable.req) do | ||
-- call a hook, adding its return value to the result | |||
miss = self:callHook(i2, hooks, v, result) | |||
if miss then | |||
-- we miss a required value for this level, so return false | |||
return false | |||
end | end | ||
1,363行目: | 1,574行目: | ||
function p.property(frame) | function p.property(frame) | ||
return p._property(frame.args) | return p._property(copyTable(frame.args)) | ||
end | end | ||
1,371行目: | 1,582行目: | ||
function p.properties(frame) | function p.properties(frame) | ||
return p._properties(frame.args) | return p._properties(copyTable(frame.args)) | ||
end | end | ||
1,379行目: | 1,590行目: | ||
function p.qualifier(frame) | function p.qualifier(frame) | ||
return p._qualifier(frame.args) | return p._qualifier(copyTable(frame.args)) | ||
end | end | ||
1,387行目: | 1,598行目: | ||
function p.qualifiers(frame) | function p.qualifiers(frame) | ||
return p._qualifiers(frame.args) | return p._qualifiers(copyTable(frame.args)) | ||
end | end | ||
1,395行目: | 1,606行目: | ||
function p.reference(frame) | function p.reference(frame) | ||
return p._reference(frame.args) | return p._reference(copyTable(frame.args)) | ||
end | end | ||
1,403行目: | 1,614行目: | ||
function p.references(frame) | function p.references(frame) | ||
return p._references(frame.args) | return p._references(copyTable(frame.args)) | ||
end | end | ||
1,449行目: | 1,660行目: | ||
_.propertyID = _.propertyID:upper() | _.propertyID = _.propertyID:upper() | ||
if _.states | if _.states.qualifiersCount > 0 then | ||
-- do further processing if "qualifier(s)" command was given | -- do further processing if "qualifier(s)" command was given | ||
if #args - nextIndex + 1 > _.states.qualifiersCount then | |||
-- claim ID or literal value has been given | -- claim ID or literal value has been given | ||
_. | nextArg = args[nextIndex] -- don't trim because might be single space representing 'somevalue' | ||
nextIndex = nextIndex + 1 | |||
_.propertyValue = nextArg | |||
end | end | ||
-- check if given qualifier ID is an alias | for i = 1, _.states.qualifiersCount do | ||
nextArg = mw.text.trim(args[nextIndex] or "") -- is a qualifierID | |||
_. | nextIndex = nextIndex + 1 | ||
-- check if given qualifier ID is an alias | |||
if aliasesP[nextArg] then | |||
nextArg = aliasesP[nextArg] | |||
end | |||
_.qualifierIDs[parameters.qualifier..i] = nextArg:upper() | |||
end | end | ||
elseif _.states[parameters.reference] then | elseif _.states[parameters.reference] then | ||
-- do further processing if "reference(s)" command was given | -- do further processing if "reference(s)" command was given | ||
1,497行目: | 1,704行目: | ||
if args["format"] then | if args["format"] then | ||
parsedFormat, formatParams = parseFormat(mw.text.trim(args["format"])) | parsedFormat, formatParams = parseFormat(mw.text.trim(args["format"])) | ||
elseif _.states | elseif _.states.qualifiersCount > 0 then | ||
if _.states[parameters.property] then | if _.states[parameters.property] then | ||
parsedFormat, formatParams = parseFormat(formats.propertyWithQualifier) | parsedFormat, formatParams = parseFormat(formats.propertyWithQualifier) | ||
1,512行目: | 1,719行目: | ||
_.separators["sep"][1] = "" | _.separators["sep"][1] = "" | ||
end | end | ||
end | |||
-- if exactly one "qualifier(s)" command has been given, make "sep%q" point to "sep%q1" to make them equivalent | |||
-- must come BEFORE overriding the separator values | |||
if _.states.qualifiersCount == 1 then | |||
_.separators["sep"..parameters.qualifier] = _.separators["sep"..parameters.qualifier.."1"] | |||
end | end | ||
1,527行目: | 1,740行目: | ||
end | end | ||
-- make sure that the separator parameter "%s" is not amongst the required parameters | -- make sure that the separator parameter "%s" is not amongst the required parameters | ||
if parsedFormat.req[parameters.separator] then | if parsedFormat.req[parameters.separator] then | ||
error(extraRequiredParameterError(parameters.separator)) | error(extraRequiredParameterError(parameters.separator)) | ||
end | end | ||
-- define the hooks that should be called (getProperty, getQualifiers, getReferences); | -- define the hooks that should be called (getProperty, getQualifiers, getReferences); | ||
-- only define a hook if both its command ("propert(y|ies)", " | -- only define a hook if both its command ("propert(y|ies)", "reference(s)", "qualifier(s)") and its parameter ("%p", "%r", "%q1", "%q2", "%q3") have been given | ||
for i, v in pairs(_.states) do | for i, v in pairs(_.states) do | ||
if formatParams[i] then | -- e.g. 'formatParams["%q1"] or formatParams["%q"]' to define hook even if "%q1" was not defined to be able to build a complete value for "%q" | ||
hooks[i] = | if formatParams[i] or formatParams[string.sub(i, 1, 2)] then | ||
hooks.count = hooks.count + 1 | hooks[i] = getHookName(i, 1) | ||
end | hooks.count = hooks.count + 1 | ||
end | end | ||
end | |||
-- create a state for "properties" if it doesn't exist yet, which will be used as a base configuration for each claim iteration; | |||
-- must come AFTER defining the hooks | -- the "%q" parameter is not attached to a state, but is a collection of the results of multiple states (attached to "%q1", "%q2", "%q3", ...); | ||
if not _.states[parameters.property] then | -- so if this parameter is given then this hook must be defined separately, but only if at least one "qualifier(s)" command has been given | ||
_.states[parameters.property] = State.new(_) | if formatParams[parameters.qualifier] and _.states.qualifiersCount > 0 then | ||
end | hooks[parameters.qualifier] = getHookName(parameters.qualifier, 1) | ||
hooks.count = hooks.count + 1 | |||
-- set the parsed format and the separators (and optional punctuation mark) | end | ||
_.states[parameters.property].parsedFormat = parsedFormat | |||
_.states[parameters.property].separator = _.separators["sep"] | -- create a state for "properties" if it doesn't exist yet, which will be used as a base configuration for each claim iteration; | ||
_.states[parameters.property].movSeparator = _.separators["sep"..parameters.separator] | -- must come AFTER defining the hooks | ||
_.states[parameters.property].puncMark = _.separators["punc"] | if not _.states[parameters.property] then | ||
_.states[parameters.property] = State.new(_) | |||
if _.entity and _.entity.claims then claims = _.entity.claims[_.propertyID] end | end | ||
if claims then | |||
-- iterate through the claims to collect values | -- set the parsed format and the separators (and optional punctuation mark) | ||
return _.states[parameters.property]:iterate(claims, hooks, State.claimMatches) -- pass property State with level 1 hooks and matchHook | _.states[parameters.property].parsedFormat = parsedFormat | ||
_.states[parameters.property].separator = _.separators["sep"] | |||
_.states[parameters.property].movSeparator = _.separators["sep"..parameters.separator] | |||
_.states[parameters.property].puncMark = _.separators["punc"] | |||
if _.entity and _.entity.claims then claims = _.entity.claims[_.propertyID] end | |||
if claims then | |||
-- first sort the claims on ranks for better performance | |||
claims = sortOnRank(claims) | |||
-- then iterate through the claims to collect values | |||
return concatValues(_.states[parameters.property]:iterate(claims, hooks, State.claimMatches)) -- pass property State with level 1 hooks and matchHook | |||
else | else | ||
return "" | return "" | ||
1,563行目: | 1,787行目: | ||
function p.label(frame) | function p.label(frame) | ||
return p._label(frame.args) | return p._label(copyTable(frame.args)) | ||
end | end | ||
1,683行目: | 1,907行目: | ||
function p.title(frame) | function p.title(frame) | ||
return p._title(frame.args) | return p._title(copyTable(frame.args)) | ||
end | end | ||
1,692行目: | 1,916行目: | ||
end | end | ||
-- main function that is supposed be used by | -- main function that is supposed to be used by wrapper templates | ||
function p.main(frame) | function p.main(frame) | ||
local f, args, i, v | local f, args, i, v | ||
1,706行目: | 1,930行目: | ||
assert(p["_"..f], 'ファンクション"' .. f .. '"が存在しません。') | assert(p["_"..f], 'ファンクション"' .. f .. '"が存在しません。') | ||
-- copy arguments from immutable to mutable table | -- copy arguments from immutable to mutable table | ||
args = copyTable(frame.args) | |||
-- remove the function name from the list | -- remove the function name from the list |