Module:Soldier: Difference between revisions
Import soldier lead module |
Title-case soldier names; keep particles, suffixes, and ASN. |
||
| Line 230: | Line 230: | ||
end | end | ||
return table.concat(out, ' ') | return table.concat(out, ' ') | ||
end | |||
local NAME_PARTICLES = { | |||
von = true, van = true, de = true, der = true, den = true, da = true, | |||
di = true, du = true, la = true, le = true, del = true, della = true, | |||
ter = true, ten = true, zu = true, zum = true, bin = true, | |||
} | |||
local NAME_SUFFIX = { | |||
jr = 'Jr', ['jr.'] = 'Jr.', sr = 'Sr', ['sr.'] = 'Sr.', | |||
esq = 'Esq', ['esq.'] = 'Esq.', | |||
ii = 'II', iii = 'III', iv = 'IV', | |||
} | |||
local function isAllCapsLetters(s) | |||
local letters = mw.ustring.gsub(s, '[^%a]', '') | |||
if mw.ustring.len(letters) < 1 then | |||
return false | |||
end | |||
return letters == mw.ustring.upper(letters) | |||
end | |||
local function isAllLowerLetters(s) | |||
local letters = mw.ustring.gsub(s, '[^%a]', '') | |||
if mw.ustring.len(letters) < 2 then | |||
return false | |||
end | |||
return letters == mw.ustring.lower(letters) | |||
end | |||
local function titleCaseWord(w) | |||
local low = mw.ustring.lower(w) | |||
if low == '' then | |||
return w | |||
end | |||
return mw.ustring.upper(mw.ustring.sub(low, 1, 1)) .. mw.ustring.sub(low, 2) | |||
end | |||
local function prettyCapsNameWord(w) | |||
local trail = '' | |||
while mw.ustring.len(w) > 0 and mw.ustring.find(mw.ustring.sub(w, -1), '[.,]') do | |||
trail = mw.ustring.sub(w, -1) .. trail | |||
w = mw.ustring.sub(w, 1, -2) | |||
end | |||
local bare = mw.ustring.gsub(w, '[^%a]', '') | |||
local up = mw.ustring.upper(bare) | |||
local len = mw.ustring.len(up) | |||
if len >= 5 and mw.ustring.sub(up, 1, 2) == 'MC' then | |||
return 'Mc' .. titleCaseWord(mw.ustring.sub(up, 3)) .. trail | |||
end | |||
if len >= 7 and mw.ustring.sub(up, 1, 3) == 'MAC' then | |||
return 'Mac' .. titleCaseWord(mw.ustring.sub(up, 4)) .. trail | |||
end | |||
return titleCaseWord(up) .. trail | |||
end | |||
local function prettyNameToken(w, isLeading) | |||
w = trim(w) | |||
if w == '' then | |||
return w | |||
end | |||
if mw.ustring.find(w, '-', 1, true) then | |||
local parts = {} | |||
local idx = 0 | |||
for part in mw.text.gsplit(w, '-', true) do | |||
idx = idx + 1 | |||
table.insert(parts, prettyNameToken(part, isLeading and idx == 1)) | |||
end | |||
return table.concat(parts, '-') | |||
end | |||
local apos = mw.ustring.find(w, "'", 1, true) | |||
if not apos then | |||
apos = mw.ustring.find(w, '’', 1, true) | |||
end | |||
if apos then | |||
local mark = mw.ustring.sub(w, apos, apos) | |||
local left = mw.ustring.sub(w, 1, apos - 1) | |||
local right = mw.ustring.sub(w, apos + 1) | |||
return prettyNameToken(left, isLeading) .. mark .. prettyNameToken(right, false) | |||
end | |||
if mw.ustring.match(w, '^(%a%.)+$') then | |||
if isAllCapsLetters(w) or isAllLowerLetters(w) then | |||
return mw.ustring.upper(w) | |||
end | |||
return w | |||
end | |||
local low = mw.ustring.lower(w) | |||
local mapped = NAME_SUFFIX[low] | |||
if mapped then | |||
return mapped | |||
end | |||
local bare = mw.ustring.gsub(w, '[^%a]', '') | |||
local lowBare = mw.ustring.lower(bare) | |||
if mw.ustring.len(bare) == 1 then | |||
local rest = mw.ustring.gsub(w, '%a', '', 1) | |||
return mw.ustring.upper(bare) .. rest | |||
end | |||
if NAME_SUFFIX[lowBare] and mw.ustring.match(w, '^%a+%.?$') then | |||
local canon = NAME_SUFFIX[lowBare] | |||
if mw.ustring.sub(w, -1) == '.' and mw.ustring.sub(canon, -1) ~= '.' then | |||
return canon .. '.' | |||
end | |||
return canon | |||
end | |||
if NAME_PARTICLES[lowBare] and mw.ustring.match(w, '^%a+$') | |||
and (isAllCapsLetters(w) or isAllLowerLetters(w)) then | |||
if isLeading then | |||
return titleCaseWord(lowBare) | |||
end | |||
return lowBare | |||
end | |||
if isAllCapsLetters(w) or isAllLowerLetters(w) then | |||
return prettyCapsNameWord(w) | |||
end | |||
return w | |||
end | |||
local function prettyNamePhrase(s, capitalizeLeadingParticle) | |||
s = trim(s) | |||
if s == '' then | |||
return s | |||
end | |||
s = mw.ustring.gsub(s, '%s*;%s*', ' ') | |||
local clauses = {} | |||
local clauseIdx = 0 | |||
for clause in mw.text.gsplit(s, ',', true) do | |||
clause = trim(clause) | |||
if clause ~= '' then | |||
clauseIdx = clauseIdx + 1 | |||
local words = splitWords(clause) | |||
local out = {} | |||
for i, w in ipairs(words) do | |||
local leading = (clauseIdx == 1 and i == 1 and capitalizeLeadingParticle) or #words == 1 | |||
local bare = mw.ustring.lower(mw.ustring.gsub(w, '[^%a]', '')) | |||
if NAME_PARTICLES[bare] and (isAllCapsLetters(w) or isAllLowerLetters(w)) then | |||
if leading then | |||
table.insert(out, titleCaseWord(mw.ustring.lower(w))) | |||
else | |||
table.insert(out, mw.ustring.lower(w)) | |||
end | |||
else | |||
table.insert(out, prettyNameToken(w, i == 1)) | |||
end | |||
end | |||
if #out > 0 then | |||
table.insert(clauses, table.concat(out, ' ')) | |||
end | |||
end | |||
end | |||
return table.concat(clauses, ', ') | |||
end | end | ||
| Line 388: | Line 542: | ||
local function prettyNamePart(s) | local function prettyNamePart(s) | ||
return prettyNamePhrase(s, false) | |||
end | end | ||
| Line 1,019: | Line 1,166: | ||
return p | return p | ||