Module:Sandbox/Ajuanca/Names Explained

-- Task 8 of GCI 2019local p =

-- Main functionfunction p.formatNames(frame) local inputName = tostring(frame.args.name) local inputLanguage = frame.args.language local fullPersonalName = p.divideName(inputName) local language = p.discoverLanguage(fullPersonalName, inputLanguage) -- Select corresponding getFamilyNames function depending -- on the language. Something like a switch. local name local str = "" if (language

"es") then name = p.esName(fullPersonalName) elseif (language

"en") then name = p.enName(fullPersonalName) elseif (language

"de") then name = p.deName(fullPersonalName) elseif (language

"zh") then name = p.zhName(fullPersonalName) elseif (language

"ru") then name = p.ruName(fullPersonalName) else return language end -- Depending on number of surnames, choose one output. if(#name.givenNames > 1) then str = "The given name is " for z, name in ipairs(name.givenNames) do str = str .. " " .. name end str = str .. ".
" else str = "The given name is " .. name.givenNames[1] .. ".
" end if(#name.familyNames > 1) then if(language

"es") then str = str .. "The first family name is " .. name.familyNames[1] .. ".
" .. "The second family name is " .. name.familyNames[2] .. "." elseif(language

"ru") then str = str .. "The family name is " .. name.familyNames[1] .. ".
" .. "The patronymic name is " .. name.familyNames[2] .. "." elseif(language

"zh") then str = str .. "The family name is " ..name.familyNames[1] .. ".
" .. "The courtesy name is " .. name.familyNames[2] .."." end else str = str .. "The family name is " .. name.familyNames[1] .. "." end return str end

-- Finds language of name-- Returns a Stringfunction p.discoverLanguage(names, supposedLanguage) local lang = "#" if (supposedLanguage ~= nil) then if (string.len(supposedLanguage)

2) then -- Array of ISO tags is compared here (no need of process if this attribute isn't given). -- Return #(message error) if ISO tag provided doesn't exist or isn't implemented. local compatibleCodes = local isCompatible = false for n, iso in ipairs(compatibleCodes) do if (supposedLanguage

iso) then isCompatible = true break end end if (isCompatible) then lang = supposedLanguage else lang = "#noCompatible" end else lang = "#incorrectFormat" end else function findLanguageMatch(name) for k, name in ipairs (names) do -- Search for indicators in each word. -- First step is compare possible know surnames that exit the normal form or cause conflicts with other -- indicators. local commonSurnames = -- Search for a common surname that scapes from previous rules. for d, specificLanguageTable in ipairs(commonSurnames) do for x, surname in ipairs(specificLanguageTable[2]) do if(surname

name) then return specificLanguageTable[1] end end end -- Spanish (es) indicators search. local accentLetters = local esCharacter = "ñ" -- preposition 'de' appears also in de. local esConnectors = local esTerminations = -- Search for accents. for a, accent in ipairs(accentLetters) do if (mw.ustring.find(name, accent)~=nil) then return "es" end end -- Search for espanish character. if(string.find(name, esCharacter)~= nil) then lang = "es" end -- Search for articles and connectors. for b, connector in ipairs(esConnectors) do if(name

connector) then return "es" end end -- Search for terminations. for c, termination in ipairs(esTerminations) do local finalLetters = string.sub(name, -2, -1) if (finalLetters

termination) then return "es" end end -- Deutsch (de) indicators search. local deCharacter = "β" local deConnectors = local deCommonSyllables = local deTerminations = -- Search for german character. if(string.find(name, deCharacter)~= nil) then return "de" end --Search for connectors. for e, connector in ipairs(deConnectors) do if(name

connector) then return "de" end end -- Search for syllables. for f, syllable in ipairs(deCommonSyllables) do if(string.find(name, syllable)~= nil) then return "de" end end -- Search for terminations. for g, termination in ipairs(deTerminations) do local finalLetters = string.sub(name, -2, -1) if (finalLetters

termination) then return "de" end end -- Russian (ru) indicators search. local patronymicsDerivations = local derivatedSurnames = -- Surnames that scape from the rest of indicators. -- Search for patronymics for s, patronymic in ipairs(patronymicsDerivations) do if((string.find(name, patronymic))~= nil)then return "ru" end end -- Search for common derivations for f, derivation in ipairs(derivatedSurnames) do if((string.find(name, derivation))~= nil) then return "ru" end end -- Chinese (zh) indicators search. local zhTerminations = -- Check for common Zh terminations for j, termination in ipairs(zhTerminations) do local finalLetters = string.sub(name, -2, -1) if (finalLetters

termination) then return "zh" end end -- Surnames beetween two and three characters, that aren't connectors of other languages -- will probably be one of the Chinease 'Hundred Family Surnames' surname. -- The only exception are abrevations. -- Now is common to find given names of just one character. if(string.len(name) <= 3) then if(string.sub(name, string.len(name))

".") then return "en" else return "zh" end end end end -- If there was no match, get name by default (en) structure. No need -- to search for english terminations. lang = findLanguageMatch(name) or "en" end return langend

-- Divides the input based on spaces. -- Returns a tablefunction p.divideName(name) local nameTable = for m in string.gmatch(name, ("%S+")) do table.insert(nameTable, m) end return nameTableend

-- Works with a spanish name, finding the given and families names.-- Returns a tablefunction p.esName(fullNameTable) name = if(not(p.isOnlyName(fullNameTable))) then table.remove(fullNameTable) end table.insert(name.givenNames, fullNameTable[1]) table.remove(fullNameTable, 1) function getPositionOfConecctors(fullNameTable) local connectors = firstSurname = 0 lastSurname = 0 for d, actualName in ipairs(fullNameTable)do for x, connector in ipairs(connectors) do if(connector

actualName) then firstSurname = d for z, lastConnector in ipairs(connectors) do if((fullNameTable[#fullNameTable-1]

lastConnector) and (firstSurname ~= #fullNameTable-1)) then lastSurname = #fullNameTable-1 return end if(fullNameTable[#fullNameTable-2]

lastConnector and (firstSurname ~= #fullNameTable-2)) then lastSurname = #fullNameTable-2 return end end end end end return end local positions = getPositionOfConecctors(fullNameTable) if(positions[1]

0) then if(#fullNameTable

1)then table.insert(name.familyNames, fullNameTable[1]) elseif(#fullNameTable

2)then -- 1st maybe is a given name local isGiven = true local terminations = for c, termination in ipairs(terminations) do local finalLetters = string.sub(fullNameTable[1], -2, -1) if (finalLetters

termination) then isGiven = false end end if(isGiven)then table.insert(name.givenNames, fullNameTable[1]) else table.insert(name.familyNames, fullNameTable[1]) end table.insert(name.familyNames, fullNameTable[2]) else table.insert(name.givenNames, fullNameTable[1]) table.insert(name.familyNames, fullNameTable[2]) table.insert(name.familyNames, fullNameTable[3]) end else if(positions[2]

0)then if(positions[1]

1) then -- Maybe a second surname is behind table.insert(name.familyNames, table.concat(fullNameTable, " ", positions[1])) elseif(positions[1]

2)then -- 1st maybe is a given name local isGiven = true local terminations = for c, termination in ipairs(terminations) do local finalLetters = string.sub(fullNameTable[1], -2, -1) if (finalLetters

termination) then isGiven = false end end if(isGiven)then table.insert(name.givenNames, fullNameTable[1]) else table.insert(name.familyNames, fullNameTable[1]) end table.insert(name.familyNames, table.concat(fullNameTable, " ", positions[1])) end else if(positions[1]

2)then table.insert(name.givenNames, fullNameTable[1]) end table.insert(name.familyNames, table.concat(fullNameTable, " ", positions[1], positions[2]-1)) table.insert(name.familyNames, table.concat(fullNameTable, " ", positions[2])) end end return nameend

-- Works with a english name, finding the given and families names.-- Returns a tablefunction p.enName(fullNameTable) name = -- Take action if some kind of suffix is given. if(not(p.isOnlyName(fullNameTable))) then table.remove(fullNameTable) end for f, actualName in ipairs(fullNameTable) do -- Only last position is family name. if(f

#fullNameTable) then table.insert(name.familyNames, actualName) else table.insert(name.givenNames, actualName) end end return nameend

-- Works with a german name, finding the given and families names.-- Returns a tablefunction p.deName(fullNameTable) name = local connectors = if(not(p.isOnlyName(fullNameTable))) then table.remove(fullNameTable) end for d, actualName in ipairs(fullNameTable)do if(d

#fullNameTable) then table.insert(name.familyNames, actualName) else for x, connector in ipairs(connectors) do if(connector

actualName) then table.insert(name.familyNames, table.concat(fullNameTable, " ", d)) return name end end table.insert(name.givenNames, actualName) end end return nameend

-- Works with a russian name, finding the given and families names.-- Returns a tablefunction p.ruName(fullNameTable) name = if(not(p.isOnlyName(fullNameTable))) then table.remove(fullNameTable) end -- Russian names are formed by a given name, the surname and a patronymic -- name. table.insert(name.givenNames, fullNameTable[1]) -- Not all people has patrynomic name. if(#fullNameTable > 2) then table.insert(name.familyNames, fullNameTable[3]) table.insert(name.familyNames, fullNameTable[2]) else table.insert(name.familyNames, fullNameTable[2]) end return nameend

-- Works with a chinease name, finding the given and families names.-- Returns a tablefunction p.zhName(fullNameTable) name = if(not(p.isOnlyName(fullNameTable))) then table.remove(fullNameTable) end table.insert(name.familyNames, fullNameTable[1]) table.remove(fullNameTable, 1) -- Appart from given name and family name, maybe a courtesy name is given. for x, eachName in ipairs(fullNameTable) do if(string.find(eachName, "%(")~=nil) then local intStart = string.find(eachName, "%(")+1 local intEnd = string.find(eachName, ")")-1 table.insert(name.familyNames, string.sub(eachName, intStart, intEnd)) else table.insert(name.givenNames, " " .. eachName) end end return nameend

-- Finds a no-name in the input-- Returns booleanfunction p.isOnlyName(tableName) local isJustName = false -- Searchs for Roman number in last name. local romanNumbers = local hasRomanNumbers = false for letter in string.gmatch(tableName[#tableName], "(%w)") do for n, romanNumber in ipairs(romanNumbers) do if (letter

romanNumber) then hasRomanNumbers = true break else hasRomanNumbers = false end end end -- Searchs for other suffixes in last name. local suffixes = local hasSuffix = false for n, suffix in ipairs(suffixes) do if (tableName[#tableName]

suffix) then hasSuffix = true end end -- Returns final boolean if (hasSuffix or hasRomanNumbers) then isJustName = false else isJustName = true end return isJustNameendreturn p