Dallime mes rishikimeve të "Moduli:IPA"
Jump to navigation
Jump to search
vNo edit summary Etiketa: Manual revert |
vNo edit summary |
||
Rreshti 1: | Rreshti 1: | ||
local | require('strict') | ||
local p = {} | |||
local | local function multiFind(s, patterns, init) | ||
local i, j = mw.ustring.find(s, patterns[1], init) | |||
for n = 2, #patterns do | |||
local i2, j2 = mw.ustring.find(s, patterns[n], init) | |||
if i2 and (not i or i2 < i) then | |||
i, j = i2, j2 | |||
local | |||
local | |||
if | |||
end | end | ||
end | end | ||
return i, j | |||
end | end | ||
local function wrapAtSpaces(s) | |||
return mw.ustring.gsub(s, '(%s+)', '<span class="wrap">%1</span>') | |||
end | |||
local | local function wrapAtSpacesSafely(s) | ||
local patterns = { | |||
'%[%[[^%]|]-%s[^%]|]-|', -- Piped links | |||
'</?[A-Za-z][^>]-%s[^>]->' -- HTML tags | |||
} | |||
local | s = mw.ustring.gsub(s, '%[%[([^%]|]-%s[^%]|]-)%]%]', '[[%1|%1]]') -- Pipe all links | ||
local t = {} | |||
local | local init | ||
while true do | |||
local i, j = multiFind(s, patterns, init) | |||
if not i then | |||
if | break | ||
end | end | ||
local pre = wrapAtSpaces(mw.ustring.sub(s, init, i - 1)) -- What precedes the match | |||
table.insert(t, pre) | |||
table.insert(t, mw.ustring.sub(s, i, j)) -- The match | |||
init = j + 1 | |||
end | end | ||
local post = wrapAtSpaces(mw.ustring.sub(s, init)) -- What follows the last match | |||
table.insert(t, post) | |||
return table.concat(t) | |||
end | |||
local function checkNamespace(isDebug) | |||
return isDebug or require('Module:Category handler').main({ true }) | |||
end | |||
local function renderCats(cats, isDebug) | |||
if not cats[1] or not checkNamespace(isDebug) then | |||
if | return '' | ||
end | end | ||
local t = {} | |||
local | for _, v in ipairs(cats) do | ||
table.insert(t, string.format( | |||
'[[%sCategory:%s]]', | |||
isDebug and ':' or '', | |||
v | |||
)) | |||
end | end | ||
return table.concat(t) | |||
end | end | ||
local function | local function resolveSynonym(s) | ||
return mw.loadData('Module:Lang/ISO 639 synonyms')[s] or s | |||
end | end | ||
local function | local function splitTag(s) | ||
local | local langCode = s:gsub('%-.*', ''):lower() | ||
langCode = resolveSynonym(langCode) | |||
local regionCode = s:match('%-(.+)') | |||
local isPrivate = regionCode and regionCode:sub(1, 2) == 'x-' | |||
return langCode, regionCode, isPrivate | |||
end | |||
local | |||
local | |||
local function getLangName(code, link, raw) | |||
return require('Module:Lang')._name_from_tag({ | |||
code, | |||
link = link, | |||
raw = raw, | |||
-- Without linking, "{{IPA}}" gets expanded in some contexts | |||
template = '[[Template:IPA|IPA]]' | |||
}) | |||
end | end | ||
local function | local function linkLang(name, target, link) | ||
return link == 'yes' and string.format( | |||
'[[%s|%s]]', | |||
target or name .. ' language', | |||
name | |||
) or name | |||
) | |||
end | end | ||
function p._main(args) | |||
local ret, cats = {}, {} | |||
local isDebug = args.debug == 'yes' | |||
local s, langCode, regionCode, isPrivate | |||
-- Guide-linking mode | |||
if args[2] and args[2] ~= '' then | |||
local data = mw.loadData('Module:IPA/data') | |||
local isGeneric = args.generic == 'yes' | |||
s = args[2] | |||
langCode, regionCode, isPrivate = splitTag(args[1]) | |||
local langData = data.langs[langCode] or {} | |||
if regionCode then | |||
if not isPrivate then | |||
regionCode = regionCode:upper() | |||
if | |||
end | end | ||
if langData.dialects and langData.dialects[regionCode] then | |||
-- Overwrite language data with the dialect's | |||
local newLangData = {} | |||
for k, v in pairs(langData) do | |||
if k ~= 'dialects' then | |||
newLangData[k] = v | |||
end | |||
end | |||
local dialectData = langData.dialects[regionCode] | |||
if dialectData.aliasOf then | |||
-- Use the canonical region code | |||
regionCode = dialectData.aliasOf | |||
isPrivate = regionCode:sub(1, 2) == 'x-' | |||
dialectData = langData.dialects[regionCode] | |||
end | |||
-- Lowercase IANA variant | |||
if dialectData.isVariant then | |||
regionCode = regionCode:lower() | |||
if | |||
end | end | ||
for k, v in pairs(dialectData) do | |||
newLangData[k] = v | |||
end | end | ||
langData = newLangData | |||
else | |||
isGeneric = true | |||
end | end | ||
end | end | ||
if | local fullLangCode = regionCode and langCode .. '-' .. regionCode | ||
-- | or langCode | ||
local langName = langData.name | |||
and linkLang(langData.name, langData.link, args.link) | |||
or getLangName(fullLangCode, args.link) | |||
if langName:sub(1, 5) == '<span' then | |||
-- Module:Lang has returned an error | |||
return langName .. renderCats({ 'IPA template errors' }, isDebug) | |||
end | end | ||
if | if args.cat ~= 'no' then | ||
local | local catLangName = langData.name | ||
if | or getLangName(fullLangCode, nil, 'yes') | ||
if catLangName:sub(1, 5) == '<span' then | |||
-- Module:Lang has returned an error, but it's not fatal | |||
table.insert(cats, 'IPA template errors') | |||
mw.addWarning(catLangName) | |||
else | |||
table.insert(cats, string.format('Pages with %s IPA', catLangName)) | |||
end | end | ||
end | end | ||
-- Label | |||
local label = args.label | |||
if not label then | |||
local labelCode = args[3] and args[3]:lower() | |||
-- | or langData.defaultLabelCode | ||
if labelCode == '' then | |||
label = '' | |||
else | |||
local langText | |||
if | if langData.text then | ||
langText = linkLang( | |||
langData.text, | |||
mw.ustring.match(langName, '^%[%[([^|%]]+)'), | |||
args.link | |||
) | |||
else | |||
if | langText = mw.ustring.gsub( | ||
langName, | |||
local | '^%[%[(([^|]+) languages)%]%]$', | ||
if | '[[%1|%2]]' | ||
) | |||
langText = mw.ustring.gsub( | |||
langText, | |||
' languages(%]?%]?)$', | |||
'%1' | |||
) | |||
end | |||
if labelCode and data.labels[labelCode] then | |||
label = data.labels[labelCode]:format(langText) | |||
else | |||
label = data.defaultLabel:format(langText) | |||
end | end | ||
end | end | ||
end | end | ||
if label and label ~= '' then | |||
local span = mw.html.create('span') | |||
:addClass('IPA-label') | |||
:wikitext(label) | |||
if args.small ~= 'no' then | |||
span:addClass('IPA-label-small') | |||
table.insert(ret, mw.getCurrentFrame():extensionTag({ | |||
name = 'templatestyles', | |||
args = { src = 'Module:IPA/styles.css' } | |||
})) | |||
end | end | ||
insert( | table.insert(ret, tostring(span) .. ' ') | ||
end | end | ||
-- Brackets | |||
s = (not isGeneric and langData.format or '[%s]'):format(s) | |||
-- Link to key | |||
local key = not isGeneric and langData.key or data.defaultKey | |||
s = string.format('[[%s|%s]]', key, s) | |||
else | |||
-- Basic mode | |||
s = args[1] | |||
if args.lang and args.lang ~= '' then | |||
langCode, regionCode, isPrivate = splitTag(args.lang) | |||
end | end | ||
if args.cat ~= 'no' then | |||
table.insert(cats, 'Pages with plain IPA') | |||
end | end | ||
end | end | ||
-- Transcription | |||
do | |||
local lang = (langCode or 'und') .. '-Latn' | |||
if not isPrivate and regionCode then | |||
lang = lang .. '-' .. regionCode | |||
end | end | ||
if | lang = lang .. '-fonipa' | ||
local span = mw.html.create('span') | |||
if | :addClass('IPA') | ||
:addClass(args.class) | |||
:attr('lang', lang) | |||
-- 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 = wrapAtSpacesSafely(s) | |||
end | end | ||
end | end | ||
if not | if (not args[2] or args[2] == '') and args.tooltip ~= '' then | ||
local | local tooltip = args.tooltip or | ||
'Representation in the International Phonetic Alphabet (IPA)' | |||
span:attr('title', tooltip) | |||
end | end | ||
s = tostring(span:wikitext(s)) | |||
table.insert(ret, s) | |||
end | end | ||
if | -- Audio | ||
insert( | local audio = args.audio ~= '' and args.audio or args[4] ~= '' and args[4] | ||
if audio then | |||
local button = mw.getCurrentFrame():expandTemplate({ | |||
title = 'Audio', | |||
args = { audio, '' } | |||
}) | |||
table.insert(ret, ' ' .. button) | |||
table.insert(cats, 'Pages including recorded pronunciations') | |||
end | end | ||
-- Categories | |||
table.insert(ret, renderCats(cats, isDebug)) | |||
return table.concat(ret) | |||
return ( | |||
end | end | ||
function p.main(frame) | |||
local args = frame:getParent().args | |||
if not args[1] then | |||
return '' | |||
function | |||
local | |||
if | |||
end | end | ||
for i, v in ipairs(args) do | |||
args[i] = mw.text.trim(v) | |||
end | end | ||
return p._main(args) | |||
return | |||
end | end | ||
return | return p |
Versioni aktual i datës 16 gusht 2025 15:32
Udhëzuesi për këtë modul mund të krijohet te Moduli:IPA/doc.
require('strict')
local p = {}
local function multiFind(s, patterns, init)
local i, j = mw.ustring.find(s, patterns[1], init)
for n = 2, #patterns do
local i2, j2 = mw.ustring.find(s, patterns[n], init)
if i2 and (not i or i2 < i) then
i, j = i2, j2
end
end
return i, j
end
local function wrapAtSpaces(s)
return mw.ustring.gsub(s, '(%s+)', '<span class="wrap">%1</span>')
end
local function wrapAtSpacesSafely(s)
local patterns = {
'%[%[[^%]|]-%s[^%]|]-|', -- Piped links
'</?[A-Za-z][^>]-%s[^>]->' -- HTML tags
}
s = mw.ustring.gsub(s, '%[%[([^%]|]-%s[^%]|]-)%]%]', '[[%1|%1]]') -- Pipe all links
local t = {}
local init
while true do
local i, j = multiFind(s, patterns, init)
if not i then
break
end
local pre = wrapAtSpaces(mw.ustring.sub(s, init, i - 1)) -- What precedes the match
table.insert(t, pre)
table.insert(t, mw.ustring.sub(s, i, j)) -- The match
init = j + 1
end
local post = wrapAtSpaces(mw.ustring.sub(s, init)) -- What follows the last match
table.insert(t, post)
return table.concat(t)
end
local function checkNamespace(isDebug)
return isDebug or require('Module:Category handler').main({ true })
end
local function renderCats(cats, isDebug)
if not cats[1] or not checkNamespace(isDebug) then
return ''
end
local t = {}
for _, v in ipairs(cats) do
table.insert(t, string.format(
'[[%sCategory:%s]]',
isDebug and ':' or '',
v
))
end
return table.concat(t)
end
local function resolveSynonym(s)
return mw.loadData('Module:Lang/ISO 639 synonyms')[s] or s
end
local function splitTag(s)
local langCode = s:gsub('%-.*', ''):lower()
langCode = resolveSynonym(langCode)
local regionCode = s:match('%-(.+)')
local isPrivate = regionCode and regionCode:sub(1, 2) == 'x-'
return langCode, regionCode, isPrivate
end
local function getLangName(code, link, raw)
return require('Module:Lang')._name_from_tag({
code,
link = link,
raw = raw,
-- Without linking, "{{IPA}}" gets expanded in some contexts
template = '[[Template:IPA|IPA]]'
})
end
local function linkLang(name, target, link)
return link == 'yes' and string.format(
'[[%s|%s]]',
target or name .. ' language',
name
) or name
end
function p._main(args)
local ret, cats = {}, {}
local isDebug = args.debug == 'yes'
local s, langCode, regionCode, isPrivate
-- Guide-linking mode
if args[2] and args[2] ~= '' then
local data = mw.loadData('Module:IPA/data')
local isGeneric = args.generic == 'yes'
s = args[2]
langCode, regionCode, isPrivate = splitTag(args[1])
local langData = data.langs[langCode] or {}
if regionCode then
if not isPrivate then
regionCode = regionCode:upper()
end
if langData.dialects and langData.dialects[regionCode] then
-- Overwrite language data with the dialect's
local newLangData = {}
for k, v in pairs(langData) do
if k ~= 'dialects' then
newLangData[k] = v
end
end
local dialectData = langData.dialects[regionCode]
if dialectData.aliasOf then
-- Use the canonical region code
regionCode = dialectData.aliasOf
isPrivate = regionCode:sub(1, 2) == 'x-'
dialectData = langData.dialects[regionCode]
end
-- Lowercase IANA variant
if dialectData.isVariant then
regionCode = regionCode:lower()
end
for k, v in pairs(dialectData) do
newLangData[k] = v
end
langData = newLangData
else
isGeneric = true
end
end
local fullLangCode = regionCode and langCode .. '-' .. regionCode
or langCode
local langName = langData.name
and linkLang(langData.name, langData.link, args.link)
or getLangName(fullLangCode, args.link)
if langName:sub(1, 5) == '<span' then
-- Module:Lang has returned an error
return langName .. renderCats({ 'IPA template errors' }, isDebug)
end
if args.cat ~= 'no' then
local catLangName = langData.name
or getLangName(fullLangCode, nil, 'yes')
if catLangName:sub(1, 5) == '<span' then
-- Module:Lang has returned an error, but it's not fatal
table.insert(cats, 'IPA template errors')
mw.addWarning(catLangName)
else
table.insert(cats, string.format('Pages with %s IPA', catLangName))
end
end
-- Label
local label = args.label
if not label then
local labelCode = args[3] and args[3]:lower()
or langData.defaultLabelCode
if labelCode == '' then
label = ''
else
local langText
if langData.text then
langText = linkLang(
langData.text,
mw.ustring.match(langName, '^%[%[([^|%]]+)'),
args.link
)
else
langText = mw.ustring.gsub(
langName,
'^%[%[(([^|]+) languages)%]%]$',
'[[%1|%2]]'
)
langText = mw.ustring.gsub(
langText,
' languages(%]?%]?)$',
'%1'
)
end
if labelCode and data.labels[labelCode] then
label = data.labels[labelCode]:format(langText)
else
label = data.defaultLabel:format(langText)
end
end
end
if label and label ~= '' then
local span = mw.html.create('span')
:addClass('IPA-label')
:wikitext(label)
if args.small ~= 'no' then
span:addClass('IPA-label-small')
table.insert(ret, mw.getCurrentFrame():extensionTag({
name = 'templatestyles',
args = { src = 'Module:IPA/styles.css' }
}))
end
table.insert(ret, tostring(span) .. ' ')
end
-- Brackets
s = (not isGeneric and langData.format or '[%s]'):format(s)
-- Link to key
local key = not isGeneric and langData.key or data.defaultKey
s = string.format('[[%s|%s]]', key, s)
else
-- Basic mode
s = args[1]
if args.lang and args.lang ~= '' then
langCode, regionCode, isPrivate = splitTag(args.lang)
end
if args.cat ~= 'no' then
table.insert(cats, 'Pages with plain IPA')
end
end
-- Transcription
do
local lang = (langCode or 'und') .. '-Latn'
if not isPrivate and regionCode then
lang = lang .. '-' .. regionCode
end
lang = lang .. '-fonipa'
local span = mw.html.create('span')
:addClass('IPA')
:addClass(args.class)
:attr('lang', lang)
-- 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 = wrapAtSpacesSafely(s)
end
end
if (not args[2] or args[2] == '') and args.tooltip ~= '' then
local tooltip = args.tooltip or
'Representation in the International Phonetic Alphabet (IPA)'
span:attr('title', tooltip)
end
s = tostring(span:wikitext(s))
table.insert(ret, s)
end
-- Audio
local audio = args.audio ~= '' and args.audio or args[4] ~= '' and args[4]
if audio then
local button = mw.getCurrentFrame():expandTemplate({
title = 'Audio',
args = { audio, '' }
})
table.insert(ret, ' ' .. button)
table.insert(cats, 'Pages including recorded pronunciations')
end
-- Categories
table.insert(ret, renderCats(cats, isDebug))
return table.concat(ret)
end
function p.main(frame)
local args = frame:getParent().args
if not args[1] then
return ''
end
for i, v in ipairs(args) do
args[i] = mw.text.trim(v)
end
return p._main(args)
end
return p