local value = object.value
local title = nil  
if value and self.linked then
if self.conf.entityID:sub(1,1) == "Q" then
title = mw.wikibase.getSitelink(self.conf.entityID)
elseif self.conf.entityID:sub(1,1) == "P" then
title = "d:Property:" .. self.conf.entityID
end  
if title then
value = buildWikilink(title, value)
end
end  
value = {value} -- 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  
-- level 1 hook
function State:getBadge(value)
value = self.conf:getLabel(value, self.rawValue, self.linked, self.shortName)  
if value == "" then
value = nil
end  
value = {value} -- 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  
function State:callHook(param, hooks, statement, result)
local valuesArray, refHash  
-- 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 matches = false
local rankPos = nil
local result, gotRequired  
for _, v in ipairs(statements) do
-- rankPos will be nil for non-claim statements (e.g. qualifiers, references, etc.)
matches, rankPos = matchHook(self, v)  
if matches then
result = {count = 0} -- collection of arrays with value objects  
local function walk(formatTable)
local miss  
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  
if result.count == hooks.count then
-- we're done if all hooks have been called;
-- returning at this point breaks the loop
return true
end
end  
for _, v2 in ipairs(formatTable) do
if result.count == hooks.count then
-- we're done if all hooks have been called;
-- returning at this point prevents further childs from being processed
return true
end  
if v2.child then
walk(v2.child)
end
end  
return true
end
gotRequired = walk(self.parsedFormat)  
-- only append the result if we got values for all required parameters on the root level
if gotRequired then
-- if we have a rankPos (only with matchHook for complete claims), then update the foundRank
if rankPos and self.conf.foundRank > rankPos then
self.conf.foundRank = rankPos
end  
-- append the result
self.results[#self.results + 1] = result  
-- break if we only need a single value
if self.singleValue then
break
end
end
end
end  
return self:out
end  
local function getEntityId(arg, eid, page, allowOmitPropPrefix)
local id = nil
local prop = nil  
if arg then
if arg:sub(1,1) == ":" then
page = arg
eid = nil
elseif arg:sub(1,1):upper == "Q" or arg:sub(1,9):lower == "property:" or allowOmitPropPrefix then
eid = arg
page = nil
else
prop = arg
end
end  
if eid then
if eid:sub(1,9):lower == "property:" then
id = replaceAlias(mw.text.trim(eid:sub(10)))  
if id:sub(1,1):upper ~= "P" then
id = ""
end
else
id = replaceAlias(eid)
end
elseif page then
if page:sub(1,1) == ":" then
page = mw.text.trim(page:sub(2))
end  
id = mw.wikibase.getEntityIdForTitle(page) or ""
end  
if not id then
id = mw.wikibase.getEntityIdForCurrentPage or ""
end  
id = id:upper  
if not mw.wikibase.isValidEntityId(id) then
id = ""
end  
return id, prop
end  
local function nextArg(args)
local arg = args[args.pointer]  
if arg then
args.pointer = args.pointer + 1
return mw.text.trim(arg)
else
return nil
end
end  
local function claimCommand(args, funcName)
local cfg = Config:new
cfg:processFlagOrCommand(funcName) -- process first command (== function name)  
local lastArg, parsedFormat, formatParams, claims, value
local hooks = {count = 0}  
-- set the date if given;
-- must come BEFORE processing the flags
if args[p.args.date] then
cfg.atDate = {parseDate(args[p.args.date])}
cfg.periods = {false, true, false} -- change default time constraint to 'current'
end  
-- process flags and commands
repeat
lastArg = nextArg(args)
until not cfg:processFlagOrCommand(lastArg)  
-- get the entity ID from either the positional argument, the eid argument or the page argument
cfg.entityID, cfg.propertyID = getEntityId(lastArg, args[p.args.eid], args[p.args.page])  
if cfg.entityID == "" then
return "" -- we cannot continue without a valid entity ID
end  
cfg.entity = mw.wikibase.getEntity(cfg.entityID)  
if not cfg.propertyID then
cfg.propertyID = nextArg(args)
end  
cfg.propertyID = replaceAlias(cfg.propertyID)  
if not cfg.entity or not cfg.propertyID then
return "" -- we cannot continue without an entity or a property ID
end  
cfg.propertyID = cfg.propertyID:upper  
if not cfg.entity.claims or not cfg.entity.claims[cfg.propertyID] then
return "" -- there is no use to continue without any claims
end  
claims = cfg.entity.claims[cfg.propertyID]  
if cfg.states.qualifiersCount > 0 then
-- do further processing if "qualifier(s)" command was given  
if #args - args.pointer + 1 > cfg.states.qualifiersCount then
-- claim ID or literal value has been given  
cfg.propertyValue = nextArg(args)
end  
for i = 1, cfg.states.qualifiersCount do
-- check if given qualifier ID is an alias and add it
cfg.qualifierIDs[parameters.qualifier..i] = replaceAlias(nextArg(args) or ""):upper
end
elseif cfg.states[parameters.reference] then
-- do further processing if "reference(s)" command was given  
cfg.propertyValue = nextArg(args)
end  
-- check for special property value 'somevalue' or 'novalue'
if cfg.propertyValue then
cfg.propertyValue = replaceSpecialChars(cfg.propertyValue)  
if cfg.propertyValue ~= "" and mw.text.trim(cfg.propertyValue) == "" then
cfg.propertyValue = " " -- single space represents 'somevalue', whereas empty string represents 'novalue'
else
cfg.propertyValue = mw.text.trim(cfg.propertyValue)
end
end  
-- parse the desired format, or choose an appropriate format
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
elseif cfg.states.qualifiersCount > 0 then -- "qualifier(s)" command given
if cfg.states[parameters.property] then -- "propert(y|ies)" command given
parsedFormat, formatParams = parseFormat(formats.propertyWithQualifier)
else
parsedFormat, formatParams = parseFormat(formats.qualifier)
end
elseif cfg.states[parameters.property] then -- "propert(y|ies)" command given
parsedFormat, formatParams = parseFormat(formats.property)
else -- "reference(s)" command given
parsedFormat, formatParams = parseFormat(formats.reference)
end  
-- if a "qualifier(s)" command and no "propert(y|ies)" command has been given, make the movable separator a semicolon
if cfg.states.qualifiersCount > 0 and not cfg.states[parameters.property] then
cfg.separators["sep"..parameters.separator][1] = {";"}
end  
-- if only "reference(s)" has been given, set the default separator to (except when raw)
if cfg.states[parameters.reference] and not cfg.states[parameters.property] and cfg.states.qualifiersCount == 0
and not cfg.states[parameters.reference].rawValue then
cfg.separators["sep"][1] = nil
end  
-- if exactly one "qualifier(s)" command has been given, make "sep%q" point to "sep%q1" to make them equivalent
if cfg.states.qualifiersCount == 1 then
cfg.separators["sep"..parameters.qualifier] = cfg.separators["sep"..parameters.qualifier.."1"]
end  
-- process overridden separator values;
-- must come AFTER tweaking the default separators