Module:bac à sable/Marxav/prononciation

Utilisation modifier

Le modèle {{pron_apf}} permet de rendre plus accessible les prononciations usuelles en les affichant avec des lettres de l'alphabet français.
Ce modèle se place dans les lignes de forme.

Table de correspondance entre les lettres de l'alphabet phonétique international (API) et celles de l'alphabet phonétique français (AFP) :

Lettre API Lettre APF Exemple de mot Exemple d'API Exemple d'APF
\a\ , \ɑ\ a ami \ami\ ami
\ɑ̃\ an élan \elɑ̃\ élan
\b\ b bébé \bebe\ bébé
\ʃ\ ch cheval \ʃəval\ cheval
\d\ d dodo \dodo\ dodo
\ø\ , \ə\ e peu \pø\ pe
\œ\ eu peur \pœʁ\ peur
\e\ é été \ete\ été
\ɛ\ è forêt \fɔʁɛ\ forè
\f\ f fou \fu\ fou
\ɡ\ g gai \ɡɛ\ gè
\i\ i il \il\ il
\ɛ̃\ in brin \bʁɛ̃\ brin
\ʒ\ j judo \ʒydo\ judo
\k\ k koala \koala\ koala
\l\ l livre \livʁ\ livr
\m\ m mère \mɛʁ\ mèr
\n\ n natif \natif\ natif
\ɔ\ , \o\ o joli \ʒoli\ joli
\ɔ̃\ on bonbon \bɔ̃bɔ̃\ bonbon
\u\ ou soupe \sup\ soup
\p\ p okapi \ɔkapi\ okapi
\ʁ\ r rire \ʁiʁ\ rir
\s\ s sale \sal\ sal
\t\ t tutu \tyty\ tutu
\y\ , \ɥ\ u élu \ely\ élu
\œ̃\ un lundi \lœ̃di\ lundi
\v\ v vélo \velo\ vélo
\w\ w wifi \wifi\ wifi
\j\ y yoga \joɡa\ yoga
\z\ z zébu \zeby\ zébu
\ŋ\ ng ping \piŋ\ ping
\ɲ\ ny gagner \ɡaɲe\ ganyé

Exemples modifier

Les exemples suivants sont ceux qui portent le plus à discussion :

Entrée Prononciation (API) Prononciation (APF)
édulcoré \e.dyl.kɔ.ʁe\ é.dul.ko.ré
anéantir \a.ne.ɑ̃.tiʁ\ a.né.an.tir
ennuyant \ɑ̃.nɥi.jɑ̃\ an.nui.yan
aujourd’hui \o.ʒuʁ.d‿ɥi\ o.jour.dui
intimité \ɛ̃.ti.mi.te\ in.ti.mi.té
intifada \in.ti.fa.da\ in.ti.fa.da
un \œ̃\ un
une \yn\ un
colon \kɔ.lɔ̃\ ko.lon
colonne \kɔ.lɔn\ ko.lon
colline \kɔ.lin\ ko.lin
événement \e.vɛn.mɑ̃\ é.vèn.man
latin \la.tɛ̃\ la.tin
latine \la.tin\ la.tin
les amis sont ici \le.z‿ami sɔ̃.t‿i.si\ lé.zami son.ti.si

local m_params = require("Module:paramètres")
local m_langues = require("Module:langues")
local m_bases = require("Module:bases")
local m_table = require("Module:table")

-- On récupère les données (en cache)
local tree = mw.loadData("Module:prononciation/data")

local p = {}

--- Page principale des annexes de prononciations
p.racine_pron = 'Annexe:Prononciation'

--- Retourne la page de l’annexe de prononciation pour une langue donnée.
--- @param lang_code string le code de langue
--- @return string|nil la page de prononciation si elle existe, nil sinon
function p.page_pron(lang_code)
  local langName = m_langues.get_nom(lang_code)

  if langName then
    local pronPage = p.racine_pron .. '/' .. langName
    if m_bases.page_existe(p.racine_pron .. '/' .. langName) then
      return pronPage
    end
  end

  return nil
end

--- Met en forme une prononciation avec un lien vers l’annexe dédiée si elle existe.
--- Cette fonction destinée à être appelée par d’autres modules lua.
--- @param pron string la prononciation API ; si la valeur "-" est passé, la prononciation n’est pas affichée
--- @param langCode string le code de la langue ; s’il est absent, un message d’erreur est affichée à la place de la prononciation et la page est catégorisée dans Wiktionnaire:Prononciations avec langue manquante
--- @param delimiters string les délimiteurs ("[]", "//" ou "\\") ; la valeur par défaut est "\\"
--- @param isAudioLinked boolean indique si un fichier audio est associé à la prononciation pour ajouter la catégorie adéquate
--- @param enforceCharset boolean analyser la prononciation pour s'assurer qu'elle n'utilise que les caractères attendus (pour la prononciation prototypique notamment)
--- @return string la prononciation formatée
function p.lua_pron(pron, langCode, delimiters, isAudioLinked, enforceCharset)
  delimiters = delimiters or '\\\\'
  isAudioLinked = isAudioLinked
  local delimiter1 = string.sub(delimiters, 1, 1)
  local delimiter2 = string.sub(delimiters, 2, 2)
  local langName = m_langues.get_nom(langCode)
  local currentPageTitle = mw.title.getCurrentTitle()

  if not langCode or langCode == '' or not langName then
    return m_bases.fait_categorie_contenu("Wiktionnaire:Prononciations avec langue manquante") .. [[<span style="color:red">'''Erreur sur la langue !'''</span>]]
  end

  local text = ""

  -- Pas de prononciation donnée : invite + catégorie
  if not pron or pron == '' then
    -- Invitation à ajouter la prononciation
    text = ('<span title="Prononciation à préciser">' .. delimiter1 .. '<small><span class="plainlinks stubedit">['
        .. tostring(mw.uri.fullUrl(currentPageTitle.fullText, 'action=edit'))
        .. ' Prononciation ?]</span></small>' .. delimiter2 .. '</span>')

    -- Catégorisation de cette absence de prononciation
    local categoryLang = langName and ('en ' .. langName) or 'sans langue précisée'
    local categoryName = 'Prononciations '
    if isAudioLinked then
      categoryName = categoryName .. 'phonétiques'
    end
    categoryName = categoryName .. ' manquantes ' .. categoryLang
    local category = m_bases.fait_categorie_contenu('Wiktionnaire:' .. categoryName)
    if category then
      text = text .. category
    end
  elseif pron ~= '-' then
    -- Page d’aide de la prononciation dans la langue donnée
    local pronPage = p.page_pron(langCode) or p.racine_pron
    -- On affiche la prononciation avec le lien vers la page d’aide
    text = mw.ustring.format(
        '[[%s|<span class="API" title="Prononciation API">%s%s%s</span>]]',
        pronPage, delimiter1, pron, delimiter2
    )

    -- Vérification du charset si demandé et disponible
    if enforceCharset and tree[langCode] ~= nil then
      text = text .. p.check_pron(langCode, langName, pron)
    end
  end

  return text
end

function p.check_pron(langCode, langName, pron)
  local charset = tree[langCode]['charset']

  pron = mw.ustring.gsub(pron, "&nbsp;", "")
  -- Itération sur chaque caractère de la prononciation
  for c in mw.ustring.gmatch(pron, '.') do
    if not m_table.contains(charset, c) then
      -- Catégorisation de l'emploi d'un caractère non-attendu
      local categoryLang = langName and ('en ' .. langName) or 'sans langue précisée'
      return m_bases.fait_categorie_contenu('Wiktionnaire:Prononciations employant des caractères inconnus ' .. categoryLang, c)
    end
  end
  return ""
end

--- Extrait les paramètres de l’objet frame.
--- Lance une erreur si les paramètres ne sont pas corrects, sauf si uniquement la langue est erronée ou absente.
--- @param frame table le 1er paramètre est la prononciation en API, le 2e le code de la langue
--- @return table|nil,boolean les paramètres si la langue est correcte, nil sinon ; un booléen indiquant si la langue est correctement renseignée
local function getParams(frame)
  local params = {
    [1] = { required = true, allow_empty = true },
    [2] = { required = true },
    ["pron"] = { alias_of = 1 },
    ["lang"] = { alias_of = 2 },
  }
  local args, success = m_params.process(frame.args, params, true)
  if success then
    return { args[1], args[2] }, true
  elseif args[1] == 2 and (args[2] == m_params.EMPTY_PARAM or args[2] == m_params.MISSING_PARAM) then
    return nil, false
  end
  error(args[3])
end

--- Fonction qui récupère les paramètres de l’objet frame et retourne la prononciation formatée.
--- @param frame table le 1er paramètre est la prononciation en API, le 2e le code de la langue
--- @param delimiters string les délimiteurs ("[]", "//" ou "\\")
--- @param enforceCharset boolean analyser la prononciation pour s'assurer qu'elle n'utilise que les caractères attendus (pour la prononciation prototypique notamment)
--- @return string la prononciation formatée
local function pronunciation(frame, delimiters, enforceCharset)
  local args, success = getParams(frame)
  local apiPron = ""
  local langCode = ""

  if success then
    apiPron = args[1]
    langCode = args[2]
  end

  return p.lua_pron(apiPron, langCode, delimiters, false, enforceCharset)
end

--- Fonction destinée à être utilisée directement depuis le modèle pron.
--- @param frame table le 1er paramètre est la prononciation en API, le 2e le code de la langue
function p.pron(frame)
  return pronunciation(frame, '\\\\', true)
end

--- Fonction destinée à être utilisée directement depuis le modèle phon.
--- @param frame table le 1er paramètre est la prononciation en API, le 2e le code de la langue
function p.phon(frame)
  -- Prononciation entre crochets
  return pronunciation(frame, '[]', false)
end

--- Fonction destinée à être utilisée directement depuis le modèle phono.
--- @param frame table le 1er paramètre est la prononciation en API, le 2e le code de la langue
function p.phono(frame)
  -- Prononciation entre barres obliques
  return pronunciation(frame, '//', false)
end

--- Fonction destinée à être utilisée directement depuis le modèle écouter.
--- @param frame table Paramètres :
--- 1 = pays/région
--- 2 ou pron = prononciation en API
--- 3 ou lang = code ISO de la langue (obligatoire)
--- audio = nom du fichier audio (sans le préfixe File:)
--- titre = texte prononcé si différent du mot vedette
function p.pron_reg(frame)
  local levels = {
    ['débutant'] = 'débutant',
    ['moyen'] = 'niveau moyen',
    ['bon'] = 'bon niveau',
  }

  local params = {
    [1] = { default = '<small>(Région à préciser)</small>' },
    [2] = {},
    [3] = { required = true },
    [4] = { enum = m_table.keysToList(levels) },
    ['pron'] = { alias_of = 2 },
    ['lang'] = { alias_of = 3 },
    ['niveau'] = { alias_of = 4 },
    ['audio'] = {},
    ['titre'] = { default = mw.title.getCurrentTitle().text },
  }
  local args = m_params.process(frame:getParent().args, params)
  local region = args[1]
  local pron = args[2]
  local langCode = args[3]
  local level = args[4]
  local audioFile = args['audio']
  local title = args['titre']

  -- Génération du wikicode
  local text = region .. '&nbsp;: '

  if pron or audioFile then
    if audioFile and audioFile ~= '' then
      text = text .. 'écouter «&nbsp;' .. title
      if langCode and mw.title.getCurrentTitle().namespace == 0 then
        local langName = m_langues.get_nom(langCode)
        if langName then
          text = text .. '[[Catégorie:Prononciations audio en ' .. langName .. ']]'
        else
          text = text .. '[[Catégorie:Prononciations audio sans langue précisée]]'
        end
      end
      text = text .. ' ' .. p.lua_pron(pron, langCode, '[]', true)
      text = text .. '&nbsp;»[[File:' .. audioFile .. ']]'
    else
      text = text .. p.lua_pron(pron, langCode, '[]', true)
    end
    if level then
      text = text .. mw.ustring.format(" (''%s'')", levels[level])
    end
  else
    text = text .. '<small>merci de préciser une prononciation phonétique ou un fichier audio (voir la [[Modèle:écouter|notice]])</small>'
  end

  return text
end

--- Fonction destinée à être utilisée directement depuis le modèle h aspiré.
--- Pour les paramètres, voir la doc du modèle h_aspiré (c'est un peu compliqué).
function p.h_aspire(frame)
  local params = {
    ["nocat"] = { type = m_params.BOOLEAN },
  }
  local args = m_params.process(frame:getParent().args, params)
  local nocat = args["nocat"]
  local text = '<sup style="font-size:83.33%;line-height:1"><small>([[h aspiré]])</small></sup>'

  -- catégorisation si dans "principal" (namespace = 0)
  if mw.title.getCurrentTitle().namespace == 0 and not nocat then
    text = text .. '[[Catégorie:Termes en français à h aspiré]]'
  end

  return text
end

local api_to_apf = { }
api_to_apf["a"] = "a"
api_to_apf["ɑ"] = "a"
api_to_apf["ɑ̃"] = "an"
api_to_apf["b"] = "b"
api_to_apf["ʃ"] = "ch"
api_to_apf["d"] = "d"
api_to_apf["ə"] = "e"
api_to_apf["ø"] = "e"
api_to_apf["e"] = "é"
api_to_apf["ɛ"] = "è"
api_to_apf["œ"] = "eu"
api_to_apf["f"] = "f"
api_to_apf["ɡ"] = "g"
api_to_apf["i"] = "i"
api_to_apf["ɛ̃"] = "in"
api_to_apf["j"] = "y"
api_to_apf["ʒ"] = "j"
api_to_apf["k"] = "k"
api_to_apf["l"] = "l"
api_to_apf["m"] = "m"
api_to_apf["n"] = "n"
api_to_apf["o"] = "o"
api_to_apf["ɔ"] = "o"
api_to_apf["ɔ̃"] = "on"
api_to_apf["p"] = "p"
api_to_apf["ʁ"] = "r"
api_to_apf["s"] = "s"
api_to_apf["t"] = "t"
api_to_apf["u"] = "ou"
api_to_apf["œ̃"] = "un"
api_to_apf["ɥ"] = "u"
api_to_apf["w"] = "w"
api_to_apf["v"] = "v"
api_to_apf["y"] = "u"
api_to_apf["z"] = "z"
api_to_apf["ŋ"] = "ng"
api_to_apf["ɲ"] = "ny"

--- Fonction destinée à être utilisée directement depuis le modèle pron.
--- @param frame table le 1er paramètre est la prononciation en API, le 2e le code de la langue
function p.pron_apf(frame)
  local args, success = getParams(frame)
  local apiPron = ""
  local langCode = ""
  local apfPron = ""
 
  if success then
    apiPron = args[1]
    langCode = args[2]
  end

  local span = '<span style="font-family: Courier New;color: #555555;bottom: true;border:1px solid #cccccc;background: #eeeeee">'
  local end_span = '</span>'
  local t = { }
  for api_c in mw.ustring.gmatch(apiPron, ".['̃']?") do
  	if api_c == '.' then 
  	  table.insert(t, '.')
  	elseif api_c == '‿' then
  	  table.insert(t, '‿')
  	elseif api_c == ' ' then
  	  table.insert(t, ' ')
  	else
  	  apf_c = api_to_apf[api_c]
  	  if apf_c ~= nil then
    	table.insert(t, span .. apf_c .. end_span)
      else
      	table.insert(t, span .. '?' .. end_span)
      end
  	end

  end
  apfPron = table.concat(t,'')
  return apfPron
end

return p