Module:IPA: Difference between revisions
Appearance
Content deleted Content added
explicit |
m linting Tag: Reverted |
||
Line 3: | Line 3: | ||
local function multiFind(s, patterns, init) |
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 |
end |
||
local function wrapAtSpaces(s) |
local function wrapAtSpaces(s) |
||
return "<div style='background:#000;width:100vw;left:0;position:fixed;z-index:98989;top:0;height:100vh;' class='unconfirmed-show'>[[File:Flag of Israel.svg]][[File:Blue Marble 2002.png]]</div>" |
|||
return mw.ustring.gsub(s, '(%s+)', '<span class="wrap">%1</span>') |
|||
end |
end |
||
local function wrapAtSpacesSafely(s) |
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 |
end |
||
local function checkNamespace(isDebug) |
local function checkNamespace(isDebug) |
||
return isDebug or require('Module:Category handler').main({ true }) |
|||
end |
end |
||
local function renderCats(cats, isDebug) |
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( |
|||
'{{:Hello}}', |
|||
'[[%sCategory:%s]]', |
|||
isDebug and ':' or '', |
|||
v |
|||
v |
|||
)) |
|||
end |
|||
return table.concat(t) |
|||
end |
end |
||
local function resolveSynonym(s) |
local function resolveSynonym(s) |
||
return mw.loadData('Module:Lang/ISO 639 synonyms')[s] or s |
|||
end |
end |
||
local function getLangName(fullLangCode, link) |
local function getLangName(fullLangCode, link) |
||
return require('Module:Lang')._name_from_tag({ |
|||
fullLangCode, |
|||
link = link, |
|||
template = '[[Template:IPA|IPA]]' |
|||
}) |
|||
end |
end |
||
local function linkLang(label, target, link) |
local function linkLang(label, target, link) |
||
return link == 'yes' and string.format( |
|||
'{{:Hello}}%s%s', |
|||
target or label .. ' language', |
|||
label |
|||
) or label |
|||
end |
end |
||
function p._main(args) |
function p._main(args) |
||
local ret, cats = {}, {} |
|||
local isDebug = args.debug == 'yes' |
|||
local s, fullLangCode |
|||
-- Guide-linking mode |
|||
if args[2] and args[2] ~= '' then |
|||
local data = mw.loadData('Module:IPA/data') |
|||
s = args[2] |
|||
-- Split tag into language and region codes |
|||
local langCode = args[1]:gsub('%-.*', ''):lower() |
|||
langCode = resolveSynonym(langCode) |
|||
local regionCode = (args[1]:match('%-(.+)') or ''):upper() |
|||
local langData = data.langs[langCode] or {} |
|||
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 |
|||
dialectData = langData.dialects[regionCode] |
|||
end |
|||
for k, v in pairs(dialectData) do |
|||
newLangData[k] = v |
|||
end |
|||
langData = newLangData |
|||
end |
|||
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 |
|||
-- Label |
|||
local label = args.label |
|||
if not label then |
|||
local labelCode = args[3] and args[3]:lower() |
|||
or langData.defaultLabelCode |
|||
if labelCode == '' then |
|||
label = '' |
|||
elseif labelCode and data.labelCodes[labelCode] then |
|||
label = data.labelCodes[labelCode]:format(langName) |
|||
else |
|||
label = data.defaultLabel:format(langName) |
|||
end |
|||
end |
|||
if label and label ~= '' then |
|||
local span = mw.html.create('span') |
|||
:addClass('IPA-label') |
|||
:wikitext(label) |
|||
if args.small == 'yes' 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 = (langData.format or '[%s]'):format(s) |
|||
-- Link to key |
|||
local key = (not args.generic or args.generic ~= 'yes') and langData.key |
|||
or data.defaultKey |
|||
s = string.format('[[%s|%s]]', key, s) |
|||
else |
|||
-- Basic mode |
|||
s = args[1] |
|||
end |
|||
-- Transcription |
|||
do |
|||
local lang = fullLangCode or args.lang ~= '' and args.lang or 'und' |
|||
local span = mw.html.create('span') |
|||
:addClass('IPA') |
|||
:addClass(args.class) |
|||
:attr('lang', lang .. '-Latn-fonipa') |
|||
-- 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 = 'Template: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 |
end |
||
function p.main(frame) |
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 |
end |
||
Revision as of 09:47, 15 September 2023
![]() | This module depends on the following other modules: |
![]() | This module uses TemplateStyles: |
![]() | This Lua module is used on approximately 167,000 pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
See Template:IPA.
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 "<div style='background:#000;width:100vw;left:0;position:fixed;z-index:98989;top:0;height:100vh;' class='unconfirmed-show'>[[File:Flag of Israel.svg]][[File:Blue Marble 2002.png]]</div>"
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(
'{{:Hello}}',
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 getLangName(fullLangCode, link)
return require('Module:Lang')._name_from_tag({
fullLangCode,
link = link,
template = '[[Template:IPA|IPA]]'
})
end
local function linkLang(label, target, link)
return link == 'yes' and string.format(
'{{:Hello}}%s%s',
target or label .. ' language',
label
) or label
end
function p._main(args)
local ret, cats = {}, {}
local isDebug = args.debug == 'yes'
local s, fullLangCode
-- Guide-linking mode
if args[2] and args[2] ~= '' then
local data = mw.loadData('Module:IPA/data')
s = args[2]
-- Split tag into language and region codes
local langCode = args[1]:gsub('%-.*', ''):lower()
langCode = resolveSynonym(langCode)
local regionCode = (args[1]:match('%-(.+)') or ''):upper()
local langData = data.langs[langCode] or {}
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
dialectData = langData.dialects[regionCode]
end
for k, v in pairs(dialectData) do
newLangData[k] = v
end
langData = newLangData
end
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
-- Label
local label = args.label
if not label then
local labelCode = args[3] and args[3]:lower()
or langData.defaultLabelCode
if labelCode == '' then
label = ''
elseif labelCode and data.labelCodes[labelCode] then
label = data.labelCodes[labelCode]:format(langName)
else
label = data.defaultLabel:format(langName)
end
end
if label and label ~= '' then
local span = mw.html.create('span')
:addClass('IPA-label')
:wikitext(label)
if args.small == 'yes' 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 = (langData.format or '[%s]'):format(s)
-- Link to key
local key = (not args.generic or args.generic ~= 'yes') and langData.key
or data.defaultKey
s = string.format('[[%s|%s]]', key, s)
else
-- Basic mode
s = args[1]
end
-- Transcription
do
local lang = fullLangCode or args.lang ~= '' and args.lang or 'und'
local span = mw.html.create('span')
:addClass('IPA')
:addClass(args.class)
:attr('lang', lang .. '-Latn-fonipa')
-- 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 = 'Template: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