Jump to content

Module:IPA: Difference between revisions

From Wikipedia, the free encyclopedia
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)
local i, j = mw.ustring.find(s, patterns[1], init)
for n = 2, #patterns do
for n = 2, #patterns do
local i2, j2 = mw.ustring.find(s, patterns[n], init)
local i2, j2 = mw.ustring.find(s, patterns[n], init)
if i2 and (not i or i2 < i) then
if i2 and (not i or i2 < i) then
i, j = i2, j2
i, j = i2, j2
end
end
end
end
return i, j
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 = {
local patterns = {
'%[%[[^%]|]-%s[^%]|]-|', -- Piped links
'%[%[[^%]|]-%s[^%]|]-|', -- Piped links
'</?[A-Za-z][^>]-%s[^>]->' -- HTML tags
'</?[A-Za-z][^>]-%s[^>]->' -- HTML tags
}
}
s = mw.ustring.gsub(s, '%[%[([^%]|]-%s[^%]|]-)%]%]', '[[%1|%1]]') -- Pipe all links
s = mw.ustring.gsub(s, '%[%[([^%]|]-%s[^%]|]-)%]%]', '[[%1|%1]]') -- Pipe all links
local t = {}
local t = {}
local init
local init
while true do
while true do
local i, j = multiFind(s, patterns, init)
local i, j = multiFind(s, patterns, init)
if not i then
if not i then
break
break
end
end
local pre = wrapAtSpaces(mw.ustring.sub(s, init, i - 1)) -- What precedes the match
local pre = wrapAtSpaces(mw.ustring.sub(s, init, i - 1)) -- What precedes the match
table.insert(t, pre)
table.insert(t, pre)
table.insert(t, mw.ustring.sub(s, i, j)) -- The match
table.insert(t, mw.ustring.sub(s, i, j)) -- The match
init = j + 1
init = j + 1
end
end
local post = wrapAtSpaces(mw.ustring.sub(s, init)) -- What follows the last match
local post = wrapAtSpaces(mw.ustring.sub(s, init)) -- What follows the last match
table.insert(t, post)
table.insert(t, post)
return table.concat(t)
return table.concat(t)
end
end


local function checkNamespace(isDebug)
local function checkNamespace(isDebug)
return isDebug or require('Module:Category handler').main({ true })
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
if not cats[1] or not checkNamespace(isDebug) then
return ''
return ''
end
end
local t = {}
local t = {}
for _, v in ipairs(cats) do
for _, v in ipairs(cats) do
table.insert(t, string.format(
table.insert(t, string.format(
'{{:Hello}}',
'[[%sCategory:%s]]',
isDebug and ':' or '',
isDebug and ':' or '',
v
v
))
))
end
end
return table.concat(t)
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
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({
return require('Module:Lang')._name_from_tag({
fullLangCode,
fullLangCode,
link = link,
link = link,
template = '[[Template:IPA|IPA]]'
template = '[[Template:IPA|IPA]]'
})
})
end
end


local function linkLang(label, target, link)
local function linkLang(label, target, link)
return link == 'yes' and string.format(
return link == 'yes' and string.format(
'[[%s|%s]]',
'{{:Hello}}%s%s',
target or label .. ' language',
target or label .. ' language',
label
label
) or label
) or label
end
end


function p._main(args)
function p._main(args)
local ret, cats = {}, {}
local ret, cats = {}, {}
local isDebug = args.debug == 'yes'
local isDebug = args.debug == 'yes'
local s, fullLangCode
local s, fullLangCode

-- Guide-linking mode
-- Guide-linking mode
if args[2] and args[2] ~= '' then
if args[2] and args[2] ~= '' then
local data = mw.loadData('Module:IPA/data')
local data = mw.loadData('Module:IPA/data')
s = args[2]
s = args[2]

-- Split tag into language and region codes
-- Split tag into language and region codes
local langCode = args[1]:gsub('%-.*', ''):lower()
local langCode = args[1]:gsub('%-.*', ''):lower()
langCode = resolveSynonym(langCode)
langCode = resolveSynonym(langCode)
local regionCode = (args[1]:match('%-(.+)') or ''):upper()
local regionCode = (args[1]:match('%-(.+)') or ''):upper()
local langData = data.langs[langCode] or {}
local langData = data.langs[langCode] or {}
if langData.dialects and langData.dialects[regionCode] then
if langData.dialects and langData.dialects[regionCode] then
-- Overwrite language data with the dialect's
-- Overwrite language data with the dialect's
local newLangData = {}
local newLangData = {}
for k, v in pairs(langData) do
for k, v in pairs(langData) do
if k ~= 'dialects' then
if k ~= 'dialects' then
newLangData[k] = v
newLangData[k] = v
end
end
end
end
local dialectData = langData.dialects[regionCode]
local dialectData = langData.dialects[regionCode]
if dialectData.aliasOf then
if dialectData.aliasOf then
-- Use the canonical region code
-- Use the canonical region code
regionCode = dialectData.aliasOf
regionCode = dialectData.aliasOf
dialectData = langData.dialects[regionCode]
dialectData = langData.dialects[regionCode]
end
end
for k, v in pairs(dialectData) do
for k, v in pairs(dialectData) do
newLangData[k] = v
newLangData[k] = v
end
end
langData = newLangData
langData = newLangData
end
end

fullLangCode = regionCode ~= ''
fullLangCode = regionCode ~= ''
and langCode .. '-' .. regionCode
and langCode .. '-' .. regionCode
or langCode
or langCode
local langName = langData.name
local langName = langData.name
and linkLang(langData.name, langData.link, args.link)
and linkLang(langData.name, langData.link, args.link)
or getLangName(fullLangCode, args.link)
or getLangName(fullLangCode, args.link)
if langName:sub(1, 5) == '<span' then
if langName:sub(1, 5) == '<span' then
-- Module:Lang has returned an error
-- Module:Lang has returned an error
return langName .. renderCats({ 'IPA template errors' }, isDebug)
return langName .. renderCats({ 'IPA template errors' }, isDebug)
end
end

-- Label
-- Label
local label = args.label
local label = args.label
if not label then
if not label then
local labelCode = args[3] and args[3]:lower()
local labelCode = args[3] and args[3]:lower()
or langData.defaultLabelCode
or langData.defaultLabelCode
if labelCode == '' then
if labelCode == '' then
label = ''
label = ''
elseif labelCode and data.labelCodes[labelCode] then
elseif labelCode and data.labelCodes[labelCode] then
label = data.labelCodes[labelCode]:format(langName)
label = data.labelCodes[labelCode]:format(langName)
else
else
label = data.defaultLabel:format(langName)
label = data.defaultLabel:format(langName)
end
end
end
end
if label and label ~= '' then
if label and label ~= '' then
local span = mw.html.create('span')
local span = mw.html.create('span')
:addClass('IPA-label')
:addClass('IPA-label')
:wikitext(label)
:wikitext(label)
if args.small == 'yes' then
if args.small == 'yes' then
span:addClass('IPA-label-small')
span:addClass('IPA-label-small')
table.insert(ret, mw.getCurrentFrame():extensionTag({
table.insert(ret, mw.getCurrentFrame():extensionTag({
name = 'templatestyles',
name = 'templatestyles',
args = { src = 'Module:IPA/styles.css' }
args = { src = 'Module:IPA/styles.css' }
}))
}))
end
end
table.insert(ret, tostring(span) .. ' ')
table.insert(ret, tostring(span) .. ' ')
end
end

-- Brackets
-- Brackets
s = (langData.format or '[%s]'):format(s)
s = (langData.format or '[%s]'):format(s)

-- Link to key
-- Link to key
local key = (not args.generic or args.generic ~= 'yes') and langData.key
local key = (not args.generic or args.generic ~= 'yes') and langData.key
or data.defaultKey
or data.defaultKey
s = string.format('[[%s|%s]]', key, s)
s = string.format('[[%s|%s]]', key, s)
else
else
-- Basic mode
-- Basic mode
s = args[1]
s = args[1]
end
end

-- Transcription
-- Transcription
do
do
local lang = fullLangCode or args.lang ~= '' and args.lang or 'und'
local lang = fullLangCode or args.lang ~= '' and args.lang or 'und'
local span = mw.html.create('span')
local span = mw.html.create('span')
:addClass('IPA')
:addClass('IPA')
:addClass(args.class)
:addClass(args.class)
:attr('lang', lang .. '-Latn-fonipa')
:attr('lang', lang .. '-Latn-fonipa')
-- wrap=all: Do nothing
-- wrap=all: Do nothing
-- wrap=none: Never break
-- wrap=none: Never break
-- Otherwise: Break at spaces only
-- Otherwise: Break at spaces only
if args.wrap ~= 'all' then
if args.wrap ~= 'all' then
span:addClass('nowrap')
span:addClass('nowrap')
if args.wrap ~= 'none' then
if args.wrap ~= 'none' then
s = wrapAtSpacesSafely(s)
s = wrapAtSpacesSafely(s)
end
end
end
end
if (not args[2] or args[2] == '') and args.tooltip ~= '' then
if (not args[2] or args[2] == '') and args.tooltip ~= '' then
local tooltip = args.tooltip or
local tooltip = args.tooltip or
'Representation in the International Phonetic Alphabet (IPA)'
'Representation in the International Phonetic Alphabet (IPA)'
span:attr('title', tooltip)
span:attr('title', tooltip)
end
end
s = tostring(span:wikitext(s))
s = tostring(span:wikitext(s))
table.insert(ret, s)
table.insert(ret, s)
end
end

-- Audio
-- Audio
local audio = args.audio ~= '' and args.audio or args[4] ~= '' and args[4]
local audio = args.audio ~= '' and args.audio or args[4] ~= '' and args[4]
if audio then
if audio then
local button = mw.getCurrentFrame():expandTemplate({
local button = mw.getCurrentFrame():expandTemplate({
title = 'Template:Audio',
title = 'Template:Audio',
args = { audio, '' }
args = { audio, '' }
})
})
table.insert(ret, ' ' .. button)
table.insert(ret, ' ' .. button)
table.insert(cats, 'Pages including recorded pronunciations')
table.insert(cats, 'Pages including recorded pronunciations')
end
end

-- Categories
-- Categories
table.insert(ret, renderCats(cats, isDebug))
table.insert(ret, renderCats(cats, isDebug))

return table.concat(ret)
return table.concat(ret)
end
end


function p.main(frame)
function p.main(frame)
local args = frame:getParent().args
local args = frame:getParent().args
if not args[1] then
if not args[1] then
return ''
return ''
end
end
for i, v in ipairs(args) do
for i, v in ipairs(args) do
args[i] = mw.text.trim(v)
args[i] = mw.text.trim(v)
end
end
return p._main(args)
return p._main(args)
end
end



Revision as of 09:47, 15 September 2023

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