Module:NationAndOccupation

From Dharmawiki
Jump to navigation Jump to search

--[[

 __  __           _       _        _   _       _   _                _              _  ___                             _   _             
|  \/  | ___   __| |_   _| | ___ _| \ | | __ _| |_(_) ___  _ __    / \   _ __   __| |/ _ \  ___ ___ _   _ _ __   __ _| |_(_) ___  _ __  
| |\/| |/ _ \ / _` | | | | |/ _ (_)  \| |/ _` | __| |/ _ \| '_ \  / _ \ | '_ \ / _` | | | |/ __/ __| | | | '_ \ / _` | __| |/ _ \| '_ \ 
| |  | | (_) | (_| | |_| | |  __/_| |\  | (_| | |_| | (_) | | | |/ ___ \| | | | (_| | |_| | (_| (__| |_| | |_) | (_| | |_| | (_) | | | |
|_|  |_|\___/ \__,_|\__,_|_|\___(_)_| \_|\__,_|\__|_|\___/|_| |_/_/   \_\_| |_|\__,_|\___/ \___\___|\__,_| .__/ \__,_|\__|_|\___/|_| |_|


This module translates a person’s nationality and profession into user’s preferred language. The template takes care for the right word order: Template:NationAndOccupation gives “French painter and poet”, if the user’s preferred language is set to English, but “pintor y poeta francés”, if the language is set to Spanish. This is especially useful with the “Description” field of Template:Creator templates.

]]

local p = {}

-- ======================================= -- === Dependencies ====================== -- ======================================= local conj = require('Module:Linguistic').conj local Wikidata = require("Module:Wikidata label") -- used for creation of name based on wikidata local q2iso = require("Module:NationAndOccupation/nationalityLUT") local n2iso = require("Module:NationAndOccupation/CountryAdjective2iso")

local function langSwitch(list,lang) local langList = mw.language.getFallbacksFor(lang) table.insert(langList,1,lang) for i,language in ipairs(langList) do if list[language] then return list[language] end end return nil end


local function getFemaleLabel(q, lang) local label = {} local entity = mw.wikibase.getEntity(q) if entity.claims and entity.claims.P2521 then -- if we have wikidata item and item has the property for _, statement in pairs( entity:getBestStatements( 'P2521' )) do local v = statement.mainsnak.datavalue if v then v = v.value label[v.language] = v.text end end end if label then return langSwitch(label,lang) else return nil end end

--[[ Implementation of Template:NationAndOccupation/default INPUTS:

  • nationality - array of string in the form compatible with Template:Nationality
  • occupation - array of already translated strings
  • gender - single gender string "male" or "female"
  • lang - users language

]] local function assembleNaO(nationality, occupation, gender, lang)

 -- Use LangSwitch to choose the style based on the language. That way template:Fallback is used

local style = langSwitch({ -- Occupation then nationality order ca=10 , es=10, eu=10, fa=10, he=10, it=10, pt=10, ro=10, vi=10, -- Occupation then nationality order with first nationality in a special form fr=11, -- Nationality then Occupation order cs=20 , da=20, el=20, en=20, eo=20, et=20, hu=20, mk=20, ml=20, nl=20, -- Nationality then Occupation order, no space zh=21, -- Nationality then Occupation order with 1st nationality in a special form and 2nd nationality upper case nds=22, de=22 , -- Nationality then Occupation order with 1st nationality in a special form and 2nd nationality lower case pl=23, ru=23, sl=23, bg=23}, lang)


-- create nationality string gender = gender or 'male' local frame = mw.getCurrentFrame() local nStr= if nationality and #nationality==1 then --Single nationality case nStr = frame:expandTemplate{ title='Nationality', args={nationality[1], gender, lang=lang} } elseif nationality then --Double nationality case local N2 = frame:expandTemplate{ title='Nationality', args={nationality[2], gender, lang=lang} } if style==11 or style==22 or style==23 then -- nationality in a special form gender = 's' end local N1 = frame:expandTemplate{ title='Nationality', args={nationality[1], gender, lang=lang} } if style==23 then N2 = mw.ustring.lower(N2) end nStr = N1 .. '-' .. N2 end

-- Create final string if occupation then local oStr = conj(occupation, lang, 'and') if style<20 then -- Type 1: Occupation then nationality order return oStr .. ' ' .. nStr elseif style==21 then -- Type 1: Nationality then Occupation order, no space return nStr .. oStr else -- Type 2: Nationality then Occupation order return nStr .. ' ' .. oStr end else return nStr end end

--[[ Implementation of Template:NationAndOccupation INPUTS:

  • entity - wikidata entity
  • lang - users language

OUTPUTS:

  • data - data structure with data extracted from Wikidata, including fields:

* nationality - array of string in the form compatible with Template:Nationality * occupation - array of already translated occupation strings * occupationEN - array of occupation strings in english * gender - single gender string "male" or "female" ]] local function harvest_wikidata(entity, lang) local occupation, occupationEN, nationality, gender local data = {}

-- if wikidata q-code is provided than look up few properties if entity then -- harvest properties from wikidata local property = {P21='gender', P27='country', P106='occupation', P172='ethnicity'} for prop, field in pairs( property ) do local n = 0; if entity.claims and entity.claims[prop] then -- if we have wikidata item and item has the property -- capture multiple "best" Wikidata value for _, statement in pairs( entity:getBestStatements( prop )) do if (statement.mainsnak.snaktype == "value") then local v = statement.mainsnak.datavalue.value.id n = n+1 if n==1 then data[field]={} end data[field][n] = v end end end end end

-- Look up gender if data.gender then if (data.gender[1]=='Q6581097' or data.gender[1]=='Q2449503') then gender = 'male' end if (data.gender[1]=='Q6581072' or data.gender[1]=='Q1052281') then gender = 'female' end end

-- Look up occupation if data.occupation then -- from wikidata local occItem = {} occupationEN = {} for i = 1,6 do if data.occupation[i] and data.occupation[i]~= then table.insert(occItem, data.occupation[i]) table.insert(occupationEN, Wikidata._getLabel(data.occupation[i], 'en', "-")) end end

occupation = {} if gender == 'female' then -- get localized (translated) occupation labels in female form for i,occ in ipairs(occItem) do table.insert(occupation, getFemaleLabel(occ, lang) or Wikidata._getLabel(occ, lang, "-")) end elseif lang=='en' then -- get English occupation labels in male form occupation = occupationEN else -- get localized (translated) occupation labels in male form for i,occ in ipairs(occItem) do table.insert(occupation, Wikidata._getLabel(occ, lang, "-")) end end end

-- Look up nationality if data.country or data.ethnicity then -- from wikidata -- process P27/country and P172/ethnicity local nTable = {} for i, v in ipairs( data.country or {} ) do table.insert(nTable, q2iso[v]) end for i, v in ipairs( data.ethnicity or {} ) do table.insert(nTable, q2iso[v]) end -- find unique values table.sort(nTable) nationality = {} if nTable[1] then table.insert(nationality, nTable[1]) end for i = 2, #nTable do if (nTable[i-1]~=nTable[i]) and nTable[i] then table.insert(nationality, nTable[i]) end end end return {nationality=nationality, occupation=occupation, gender=gender, occupationEN=occupationEN} end

--[[ Implementation of Template:NationAndOccupation INPUTS:

  • args.nationality - '/' separated string with substrings in the form compatible
                    with Template:Nationality
  • args.occupation - '/' separated string with substrings with english names of
                    occupations compatible with Template:Occupations
  • args.gender - single gender string "male" or "female"
  • args.wikidata - wikidata q-code
  • args.lang - users language

OUTPUTS:

  • OutStr - string with transpaced phrase like "english writer"
  • args - data structure with processed inputs
  • data - data structure with data extracted from Wikidata

]] function p._NationAndOccupation(args0) local occupation, nationality, entity, occupationEN

-- if wikidata q-code is provided than look up few properties local q = args0.wikidata if q and type(q)=='string' and string.sub(q,1,1)=="Q" then -- entity = mw.wikibase.getEntity(q) elseif q then entity = q end local data = harvest_wikidata(entity, args0.lang) local gender = args0.gender or data.gender

-- Look up occupation if args0.occupation then -- from input arguments local frame = mw.getCurrentFrame() occupationEN = mw.text.split(args0.occupation or , '/') occupation = {} for i = 1,6 do if occupationEN[i] and occupationEN[i]~= then table.insert(occupation, frame:expandTemplate{ title='Occupation', args={occupationEN[i], gender, lang=args0.lang, category=category} }) end end end

-- Look up nationality if args0.nationality then -- from input arguments nationality = mw.text.split(args0.nationality or , '/') for i = 1,2 do -- if nationality is a word than see if we can find iso code local N = string.lower(nationality[i] or ) if #N>2 and n2iso[N] then nationality[i] = n2iso[N] end end end local outStr = assembleNaO(nationality or data.nationality, occupation or data.occupation, gender, args0.lang) local args = {nationality=nationality, occupation=occupation, gender=args0.gender, occupationEN=occupationEN}

return outStr, args, data end

--[[ NationAndOccupation

This function is the core part of the NationAndOccupation template.

Usage: Script error: You must specify a function to call.

Parameters:
 *nationality - '/' separated string with substrings in the form compatible 
                    with Template:Nationality
 * occupation  - '/' separated string with substrings with english names of 
                    occupations compatible with Template:Occupations
 * gender      - single gender string "male" or "female"
 * wikidata    - wikidata q-code
 * lang        - users language
Error Handling:

]] function p.NationAndOccupation(frame) local args0 = {} for name, value in pairs( frame.args ) do value = string.gsub(value,"\/+$", "") -- remove /// on the end value = string.gsub(value,"%s*$", "") -- remove whitespaces on the end value = string.gsub(value,"^%s*", "") -- remove whitespaces at the beggining if value ~= then -- nuke empty strings local name1 = string.gsub( string.lower(name), ' ', '_') args0[name1] = value end end if not (args0.lang and mw.language.isSupportedLanguage(args0.lang)) then args0.lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language end local outStr, args, data = p._NationAndOccupation(args0) return outStr end

return p