Documentation for this module may be created at Module:Sandbox/Nardog/5/doc
require('strict')
local p = {}
local function multiFind(s, t)
local i, j = mw.ustring.find(s, t[1])
for n = 2, #t do
local i2, j2 = mw.ustring.find(s, t[n])
if i2 and (not i or i2 < i) then
i, j = i2, j2
end
end
return i, j
end
local function wrapSpaces(s)
return mw.ustring.gsub(s, '(%s+)', '<span class="wrap">%1</span>')
end
local function escapeAndWrapSpaces(s)
local patterns = {
'%[%[[^%]|]-%s[^%]|]-|', -- Piped links
'</?[A-Za-z][^>]-%s[^>]->' -- HTML tags
}
s = mw.ustring.gsub(s, '%[%[([^%]|]-%s[^%]|]-)%]%]', '[[%1|%1]]') -- Pipe unpiped links
local i, j = multiFind(s, patterns)
if i then -- Match found
local remaining, escaped = {}, {}
repeat
table.insert(remaining, mw.ustring.sub(s, 1, i - 1)) -- What precedes the match
table.insert(escaped, mw.ustring.sub(s, i, j)) -- The match
s = mw.ustring.sub(s, j + 1) -- Truncate
i, j = multiFind(s, patterns)
until not i
table.insert(remaining, s) -- What follows the last match
s = {}
for k, v in ipairs(remaining) do
v = wrapSpaces(v)
table.insert(s, v)
table.insert(s, escaped[k])
end
s = table.concat(s)
else
s = wrapSpaces(s)
end
return s
end
local function checkNamespace()
return require('Module:Category handler').main{ true }
end
local function renderCats(cats)
local s = ''
if cats and cats[1] and checkNamespace() then
s = {}
for _, v in ipairs(cats) do
table.insert(s, '[[Category:' .. v .. ']]')
end
s = table.concat(s)
end
return s
end
local function renderError(s)
return '<span class="error">' .. s .. '</span>' ..
renderCats({ 'IPA template errors' })
end
function p._main(args, isConv)
local function resolveSynonym(s)
s = s:lower()
return mw.loadData('Module:Lang/ISO 639 synonyms')[s] or s
end
local function getLangName(s)
return require('Module:Lang')._name_from_tag({ s, link = args.link, template = 'IPA' })
end
local function makeLink(s, target)
return args.link == 'yes'
and string.format('[[%s%s]]', target and target .. '|' or '', s)
or s
end
local function makeSmallText(s)
if args.small == 'no' then -- Defaults to yes
return s
end
local span = mw.html.create('span')
:css('font-size', '85%')
:wikitext(s)
return tostring(span)
end
local ret, cats = {}, {}
local s, label, langCode
if args[2] then
local data = mw.loadData('Module:Sandbox/Nardog/5d')
local convArgs
if isConv then
convArgs = mw.clone(args)
table.remove(convArgs, 1)
else
s = args[2]
end
langCode = resolveSynonym(args[1])
local langData = data.langs[langCode]
local langName = langData and langData.name
langName = langName and makeLink(langName, langData.link)
or getLangName(langCode, args.link)
local key = langData and langData.key or data.defKey
label = args.label
if langName:sub(1, 5) == '<span' then
return langName .. renderCats({ 'IPA template errors' })
elseif not label then
local function returnLabel()
local labelCode = isConv and args[2] or args[3]
if labelCode then
if labelCode == '' then
return ''
end
local customCodes = langData and langData.labels
if customCodes and customCodes[labelCode] then
return customCodes[labelCode]
end
local dialects = langData and langData.dialects
if dialects then
for codePat, labelPat in pairs(data.defDiaCodes) do
for diaCode, diaName in pairs(dialects) do
if labelCode == codePat:format(diaCode) then
return labelPat:format(makeLink(
diaName, dialects[diaCode .. '-link']))
end
end
end
end
local defLabelMatch = data.defLabels[labelCode]
if defLabelMatch then
return defLabelMatch:format(langName)
end
end
end
label = returnLabel()
if label then
if isConv then
table.remove(convArgs, 1)
end
else
local defLabel = langData and langData.defLabel or data.defLabel
label = defLabel:format(langName)
end
end
if label and label ~= '' then
label = makeSmallText(label) or label
table.insert(ret, label .. ' ')
end
if isConv then
local module = langData and langData.convModule
if module then
local hasError
s, hasError = require(module).main(convArgs)
if hasError then
local errorCat = langData.convErrorCat
if errorCat then
table.insert(cats, errorCat)
end
end
if langData.convArgs then
for k, v in pairs (langData.convArgs) do
args[k] = args[k] or v
end
end
if langData.convStyles then
table.insert(ret, 1, mw.getCurrentFrame():extensionTag{
name = 'templatestyles',
args = { src = langData.convStyles }
})
end
else
return renderError('IPA convert module not found for \'' .. langCode .. '\'')
end
end
s = langData and langData.slashes and '/' .. s .. '/' or '[' .. s .. ']'
s = string.format('[[%s|%s]]', key, s)
if langData.iso then
langCode = langData.iso ~= 'none' and langData.iso
end
else
s = args[1]
end
-- Transcription
do
local span = mw.html.create('span')
:attr('lang', (langCode or 'und') .. '-fonipa')
:addClass('IPA')
:addClass(args.class)
-- wrap=all: Do nothing
-- wrap=none: Never break
-- Otherwise: Break at spaces only
if args.wrap ~= 'all' then
span:addClass('nowrap')
if args.wrap ~= 'none' then
s = escapeAndWrapSpaces(s)
end
end
if not args[2] and args.tooltip ~= '' then -- tooltip is added unless blank
span:attr('title', args.tooltip or
'Representation in the International Phonetic Alphabet (IPA)')
end
s = tostring(span:wikitext(s))
table.insert(ret, s)
end
-- Audio
local audio = args.audio ~= '' and args.audio or not isConv and args[4] ~= '' and args[4]
if audio then
audio = '(' .. mw.getCurrentFrame():expandTemplate{
title = 'Template:Audio',
args = { audio, 'listen', help = 'no' }
} .. ')'
audio = makeSmallText(audio) or audio
table.insert(ret, ' ' .. audio)
table.insert(cats, 'Pages including recorded pronunciations')
end
-- Categories
table.insert(ret, renderCats(cats))
return table.concat(ret)
end
function p.main(frame)
-- local args = frame:getParent().args
local args = frame.args[1] and frame.args or frame:getParent().args
for i, v in ipairs(args) do
local s = mw.text.trim(v)
args[i] = (s ~= '' or i == 3) and s
end
return args[1] and p._main(args)
end
function p._convert(args)
return p._main(args, true)
end
function p.convert(frame)
local args = {}
-- for i, v in ipairs(frame:getParent().args) do
for i, v in ipairs(frame.args[1] and frame.args or frame:getParent().args) do
local s = mw.text.trim(v)
if s ~= '' or i == 2 then
table.insert(args, s)
end
end
-- for k, v in pairs(frame:getParent().args) do
for k, v in pairs(frame.args[1] and frame.args or frame:getParent().args) do
if type(k) == 'string' then
args[k] = v
end
end
return args[1] and args[2] and p._convert(args)
end
return p