Module:Sandbox/AbstractWikipedia/Constructors
The Constructors module creates abstract content for the use of the NLG Scribunto prototype.
Each one of the publicly-exposed function (with the exception of the Constructors
function) returns a constructor of a specific type, corresponding to the name of the function (e.g. the Birth
function will return a Birth
constructor). In general, the constructor will be instantiated with data from the Wikidata item corresponding to the given Q-id (an exception is the Age function which instantiates the constructor using the data given in two other constructors, namely Birth
and Death
). In order to facilitate access to Wikidata properties, the module uses the Wikidata module.
In a Wikifunctions implementation, these constructor-creation functions would probably be user-supplied Wikifunctions functions.
The Constructors
function
[edit]The Constructors
function is special in that it returns a list of instantiated constructors, which correspond to the abstract content which should be verbalized for a given topic (identified by its Q-id). First, the function will attempt to retrieve manually-curated abstract content (which is stored in the Abstract Content module). If that doesn't exist, it will attempt to dynamically assemble abstract content depending to the type of the Q-id's item. Currently only items which refer to people are supported. If no abstract content can be assembled, an error is raised.
local p = {}
local ac = require("Module:Sandbox/AbstractWikipedia/AbstractContent")
local wd = require("Module:Sandbox/AbstractWikipedia/Wikidata")
-- Helper function to insert information into constructor
-- Returns true if inserted, false otherwise
local function insertIfNotNil (constructor, field, value)
if value then
constructor[field] = value
return true
end
return false
end
-- Helper function to return a date associated with a q_id through property p_id
local function getDate (q_id, p_id)
local property = wd.getProperty(q_id, p_id, "time")
if not property then
return nil
end
local time_string = property["time"]
if not time_string then return nil end
local result = { _predicate = "Date", year = '', month = '', day = ''}
_, _, result.year, result.month, result.day = string.find(time_string, "(-?%d+)-(%d+)-(%d+)T")
return result
end
function p.Birth ( q_id )
local c = { _predicate = 'Birth', person = q_id } -- Constructor to build
local added
added = insertIfNotNil(c, "date", getDate(q_id, "P569"))
added = insertIfNotNil(c, "place", wd.getItemId(q_id, "P19")) or added
if added then
return c
end
return nil
end
function p.Death ( q_id )
local c = { _predicate = 'Death', person = q_id } -- Constructor to build
local added
added = insertIfNotNil(c, "date", getDate(q_id, "P570"))
added = insertIfNotNil(c, "place", wd.getItemId(q_id, "P20")) or added
if added then
return c
end
return nil
end
-- Calculates the age of a person at the reference date in years
function calculateAge (birth, reference)
local age = tonumber(reference.year) - tonumber(birth.year)
if (tonumber(reference.month) < tonumber(birth.month) or tonumber(reference.day) < tonumber(birth.day)) then
age = age - 1
end
return age
end
-- Returns age of person today if living, or age at death
function p.Age (q_id, birth, death)
local c = { _predicate = "Age", person = q_id } -- Constructor to build
if not birth or not birth.date then return nil end
if not death or not death.date then
c.age=calculateAge(birth.date, os.date("*t"))
c.alive = true
else
c.age=calculateAge(birth.date, death.date)
c.alive = false
end
return c
end
-- Build a constructor for people
function p.Person ( q_id )
local c = { _predicate = "Person", person = q_id } -- Constructor to build
insertIfNotNil(c, "origin", wd.getItemId(q_id, "P27"))
insertIfNotNil(c, "occupation", wd.getItemId(q_id, "P106"))
insertIfNotNil(c, "birth", p.Birth(q_id))
insertIfNotNil(c, "death", p.Death(q_id))
insertIfNotNil(c, "age", p.Age(q_id, c.birth, c.death))
return c
end
-- Returns a list of constructors appropriate for the q_id.
-- This is either fetched from the abstract content repository or built
-- according to the type of the item.
function p.Constructors ( q_id )
if ac[q_id] then -- Check if individually curated abstract content exists
return ac[q_id]
elseif wd.isHuman(q_id) then
return { p.Person(q_id) }
end
error("Constructors can currently support only entites which refer to people")
end
return p