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)
s = trim(s)
return prettyNamePhrase(s, false)
if s == '' then
return s
end
if isAllCapsPhrase(s) then
return prettyTitle(s, false)
end
return s
end
end


Line 1,019: Line 1,166:


return p
return p