Module:pt-pronunc/testcases

local tests = require("Module:UnitTests") local m_pt_pronunc = require("Module:pt-pronunc") local m_links = require("Module:links") local m_table = require("Module:table") local pt = require("Module:languages").getByCode("pt")

local rsplit = mw.text.split

local function tag_IPA(IPA) return ' ' .. IPA .. ' ' end

local function link(text) return m_links.full_link{ term = text, lang = pt } end

local options = { display = tag_IPA }

local all_style_set = m_table.listToSet(m_pt_pronunc.all_styles)

--[=[ In the following examples, each line is either a section header beginning with a # or an example. Examples consist of tab-separated fields. The first field is the actual spelling of the term in question. Each following field consaists of a respelling associated with a particular style and the corresponding expected IPA pronunciation. A style corresponds approximately to a particular dialect and is one of the following:

(1) A "basic style": * "gbr" = "General" Brazilian * "sp" = São Paulo * "rio" = Rio de Janeiro * "cpt" = Portugal outside of Lisbon (2) A "combined style": * "br" = Brazil = "gbr" + "sp" + "rio" * "pt" = Portugal = "gpt" + "cpt" * "all" = all basic styles (3) A "style group", which is a list of hyphen-separated styles; * e.g. "br-cpt" = "br" + "cpt" = "gbr" + "sp" + "rio" + "cpt"

If a combined style or style group is specified, the respelling applies to all individual styles.

The format of a respelling field is RESPELLING:IPA (respelling associated with all styles) or STYLE=RESPELLING:IPA (respelling associated with the specified style). If RESPELLING is omitted (but the colon kept), the term's original spelling is used. IPA in turn is either a single expected IPA pronunciation (between /.../ to represent phonemic pronunciation or between [...] to represent phonetic pronunciation), a style-tagged pronunciation of the form STYLE=PRONUN, or a semicolon-separated list of style-tagged pronunciations.

Examples:

This means the word Hungria, respelled the same way (note the omitted respelling before the colon), has the expected phonetic pronunciation [ũˈɡɾi.ɐ] in all styles (dialects). The actual pronunciation for all styles will be generated, and the phonetic output of each in turn will be compared against [ũˈɡɾi.ɐ]. Phonemic output will not be checked. This means the word jogging has the respelling 'djógguing' and expected phonemic pronunciation /ˈd͡ʒɔ.ɡĩ/ in all Brazilian styles. Portugal styles are omitted and will not be checked. This means the word abrangência has the respelling 'abrangêncya' for all styles, which in turn has the expected phonemic pronunciation /a.bɾɐ̃ˈʒẽ.sjɐ/ in Brazil and expected phonetic pronunciation [ɐ.βɾɐ̃ˈʒẽ.sjɐ] in Portugal. The phonemic pronunciation for all Brazilian styles ("General" Brazilian, Rio and São Paulo) will be checked against /a.bɾɐ̃ˈʒẽ.sjɐ/, and the phonetic pronunciation for all Portugal styles (Lisbon as well a  non-Lisbon Central Portugal) will be checked against [ɐ.βɾɐ̃ˈʒẽ.sjɐ]. This means the word ninguém, respelled the same way for all styles, has the phonemic pronunciation /nĩˈɡẽj̃/ in all styles other than Lisbon, and /nĩˈɡɐ̃j̃/ in Lisbon. This means the term long neck has two possible respellings 'lòngh nécke' and 'lòngue nécke' in Brazil, with expected respective phonemic pronunciations /ˌlõɡ ˈnɛ.ki/ and /ˌlõ.ɡi ˈnɛ.ki/. Portugal styles will not be checked. This means the word distinguir has respelling 'distinguir' in Portugal with expected phonetic pronunciation [diʃ.tĩˈɡiɾ] in Portugal (both Lisbon and elsewhere in Central Portugal), but has the respelling 'distingüir' in Brazil. The Brazilian respelling has different phonetic pronunciations [d͡ʒis.t͡ʃĩˈɡwi(h)] in "General" Brazilian, [d͡ʒiʃ.t͡ʃĩˈɡwi(χ)] in Rio and [d͡ʒis.t͡ʃĩˈɡwi(ɾ)] in São Paulo. ]=] local examples = [[ as pessoas	as pessôas:pt=[ɐʃ pɨˈso.ɐʃ] às pessoas	às pessôas:pt=[aʃ pɨˈso.ɐʃ] saca	:[ˈsa.kɐ] acá	:pt=[ɐˈka];br=[aˈka]
 * Hungria	:[ũˈɡɾi.ɐ]
 * jogging	br=djógguing:/ˈd͡ʒɔ.ɡĩ/
 * abrangência	abrangêncya:br=/a.bɾɐ̃ˈʒẽ.sjɐ/;pt=[ɐ.βɾɐ̃ˈʒẽ.sjɐ]
 * ninguém	:br-cpt=/nĩˈɡẽj̃/;lisbon=/nĩˈɡɐ̃j̃/
 * long neck	br=lòngh nécke,lòngue nécke:/ˌlõɡ ˈnɛ.ki/,/ˌlõ.ɡi ˈnɛ.ki/
 * distinguir	pt=distinguir:[diʃ.tĩˈɡiɾ]	br=distingüir:gbr=[d͡ʒis.t͡ʃĩˈɡwi(h)];rio=[d͡ʒiʃ.t͡ʃĩˈɡwi(χ)];sp=[d͡ʒis.t͡ʃĩˈɡwi(ɾ)]
 * a

baba	:/ˈba.bɐ/ baba	:br=[ˈba.bɐ];pt=[ˈba.βɐ] a baba	:br=[a ˈba.bɐ];pt=[ɐ ˈβa.βɐ] braça	:[ˈbɾa.sɐ] abraça	:br=[aˈbɾa.sɐ];pt=[ɐˈβɾa.sɐ] a braça	:br=[a ˈbɾa.sɐ];pt=[ɐ ˈβɾa.sɐ]
 * b

cóccix	:br=/ˈkɔk.siks/ occitano	br=occitano:/ok.siˈtɐ̃.nu/
 * cc

de	:br=[d͡ʒi];pt=[dɨ] praça de Londres	:pt=[ˈpɾa.sɐ ðɨ ˈlõ.dɾɨʃ];rio=[ˈpɾa.sɐ d͡ʒi ˈlõ.dɾiʃ];gbr-sp=[ˈpɾa.sɐ d͡ʒi ˈlõ.dɾis] Pedro	Pêdro:br=[ˈpe.dɾu];pt=[ˈpe.ðɾu] os dentes	:rio=[uʒ ˈdẽ.t͡ʃiʃ];gbr-sp=[uz ˈdẽ.t͡ʃis];pt=[uʒ ˈðẽ.tɨʃ];pt=[uʒ ˈdẽ.tɨʃ] adjetivo	:br=/ad.ʒeˈt͡ʃi.vu/ Reguengos de Monsaraz	:pt=[ʁɨˈɣẽ.ɡuʒ ðɨ mõ.sɐˈɾaʃ];pt=[ʁɨˈɣẽ.ɡuʒ dɨ mõ.sɐˈɾaʃ]
 * d

elegante	:pt=/i.lɨˈɡɐ̃.tɨ/ eterno	etérno:pt=/iˈtɛɾ.nu/ pregar	:pt=/pɾɨˈɡaɾ/;gbr-rio=/pɾeˈɡa(ʁ)/;sp=/pɾeˈɡa(ɾ)/ pregar	pt=prègar:/ˌpɾɛˈɡaɾ/ eleito	:br=/eˈlej.tu/ ema	:br=/ˈẽ.mɐ/ exame	ezame:pt=/iˈzɐ.mɨ/;br=/eˈzɐ̃.mi/ exames	ezames:pt=/iˈzɐ.mɨʃ/;rio=/eˈzɐ̃.miʃ/;gbr-sp=/eˈzɐ̃.mis/ córtex	:pt-sp=/ˈkɔɾ.tɛks/;rio-gbr=/ˈkɔʁ.tɛks/ desde	pt=dêsde:/ˈdeʒ.dɨ/ mesmo	pt=mêsmo:/ˈmeʒ.mu/ português	:pt=/puɾ.tuˈɡeʃ/ vês	:pt=/ˈveʃ/ líder	:pt=/ˈli.dɛɾ/ cadáver	:pt=/kɐˈda.vɛɾ/ repórter	:pt=/ʁɨˈpɔɾ.tɛɾ/
 * e

obra	pt=óbra:/ˈɔ.bɾɐ/ obrar	:pt=/ɔˈbɾaɾ/ olho	pt=ôlho:/ˈo.ʎu/ olho	pt=ólho:/ˈɔ.ʎu/ olhar	:pt=/ɔˈʎaɾ/ odor	pt=odôr:/ɔˈdoɾ/ obrigado	:pt=/ɔ.bɾiˈɡa.du/ oculto	:pt=/ɔˈkul.tu/ operar	:pt=/ɔ.pɨˈɾaɾ/ oração	:pt=/ɔ.ɾɐˈsɐ̃w̃/ Holanda	:pt=/ɔˈlɐ̃.dɐ/ homófono	:pt=/ɔˈmɔ.fu.nu/ hospital	:pt=/ɔʃ.piˈtal/ O Porto	O Pôrto:pt=[u ˈpoɾ.tu] Os Lobos	Os Lôbos:pt=[uʒ ˈlo.βuʃ]
 * 1) initial o

guerra	guérra:/ˈɡɛ.ʁɐ/ a guerra	a guérra:rio=[a ˈɡɛ.χɐ];sp-gbr=[a ˈɡɛ.hɐ];pt=[ɐ ˈɣɛ.ʁɐ] guarda	:rio-gbr=/ˈɡwaʁ.dɐ/;sp-pt=/ˈɡwaɾ.dɐ/ gelo	gêlo:/ˈʒe.lu/
 * g

elo	élo:/ˈɛ.lu/ velho	vélho:/ˈvɛ.ʎu/ conselho	consêlho:gpt=[kõˈsɐ(j).ʎu];br-cpt=/kõˈse.ʎu/
 * l, lh

mal	:pt=/ˈmal/;br=/ˈmaw/ mal	:pt=[ˈmaɫ];br=[ˈmaʊ̯] calca	:pt=[ˈkaɫ.kɐ];br=[ˈkaʊ̯.kɐ] alto	:pt=[ˈaɫ.tu];br=[ˈaʊ̯.tu] alpaca	:pt=[aɫˈpa.kɐ];br=[aʊ̯ˈpa.kɐ] anel	anél:pt=/ɐˈnɛl/;br=/aˈnɛw/ anel	anél:pt=[ɐˈnɛɫ];br=[aˈnɛʊ̯] feltro	féltro:pt=/ˈfɛl.tɾu/ helvético	:pt=/ɛlˈvɛ.ti.ku/ relvado	:pt=[ʁɛɫˈva.ðu];spt=[ʁɛɫˈva.du] evitável	:pt=/i.viˈta.vɛl/ Belmonte	:pt=/bɛlˈmõ.tɨ/ palpável	:br=[paʊ̯ˈpa.veʊ̯];pt=[paɫˈpa.vɛɫ] bolsa	bôlsa:br=/ˈbow.sɐ/;pt=/ˈbol.sɐ/ bolsa	bôlsa:br=[ˈboʊ̯.sɐ];pt=[ˈboɫ.sɐ] bolsada	:pt=[boɫˈsa.ðɐ];spt=[boɫˈsa.dɐ] polvilhar	:pt=[poɫ.viˈʎaɾ] molda	mólda:pt=[ˈmɔɫ.dɐ] moldar	mọldar:pt=[mɔɫˈdaɾ] soldado	:pt=[soɫˈda.ðu];spt=[soɫˈda.du] soldado	sọldado:pt=[sɔɫˈda.ðu];spt=[sɔɫˈda.du] álcool	:pt=[aɫ.ˈkwɔɫ] azul e branco	:br=[aˈzuʊ̯ i ˈbɾɐ̃.ku];pt=[ɐˈzul i ˈβɾɐ̃.ku]
 * 1) Coda l

mau	:/ˈmaw/ mau	:pt=[ˈmaw];br=[ˈmaʊ̯] auto	:pt=/ˈaw.tu/ aumenta	:pt=/awˈmẽ.tɐ/
 * 1) Diphthong au

vai	:/ˈvaj/ Cairo	:/ˈkaj.ɾu/ airoso	airôso:/ajˈɾo.zu/ bailado	:pt=/bajˈla.du/
 * 1) Diphthong ai

ano	:br=/ˈɐ̃.nu/;pt=/ˈɐ.nu/ cama	:br=/ˈkɐ̃.mɐ/;pt=/ˈkɐ.mɐ/ entendo	:br=/ĩˈtẽ.du/;pt=/ẽˈtẽ.du/ falámos	:pt=/fɐˈla.muʃ/ andaime	:pt=/ɐ̃ˈdaj.mɨ/;br=[ɐ̃ˈdɐ̃ɪ̯̃.mi] andaime	andáime:br=[ɐ̃ˈdaɪ̯.mi] Jaime	Jáime:br=/ˈʒaj.mi/ Jaime	:br=/ˈʒɐ̃j̃.mi/;pt=/ˈʒaj.mɨ/ regímen	:br=/ʁeˈʒĩ.mẽj̃/;pt=/ʁɨˈʒi.mɛn/ Renan	:br=/ʁeˈnɐ̃/;pt=/ʁɨˈnan/ íon	:br=/ˈi.õ/;pt=/ˈi.ɔn/ Bombaim	:br=/bõ.baˈĩ/;pt=/bõ.bɐˈĩ/ Coimbra	:br=/koˈĩ.bɾɐ/ saindo	:br=/saˈĩ.du/;pt=/sɐˈĩ.du/ fauna	:br=/ˈfɐ̃w̃.nɐ/ Iaundé	:br=/ja.ũˈdɛ/;pt=/jɐ.ũˈdɛ/
 * m, n

bem	:pt=/ˈbɐ̃j̃/ bens	:pt=/ˈbɐ̃j̃ʃ/ também	:br=/tɐ̃ˈbẽj̃/;pt=/tɐ̃ˈbɐ̃j̃/ ninguém	:br=/nĩˈɡẽj̃/;pt=/nĩˈɡɐ̃j̃/ parabéns	:gbr-sp=/pa.ɾaˈbẽj̃s/;rio=/pa.ɾaˈbẽj̃ʃ/;pt=/pɐ.ɾɐˈbɐ̃j̃ʃ/
 * 1) Final -em/-ens

abrangência	abrangêncya:br=/a.bɾɐ̃ˈʒẽ.sjɐ/;pt=[ɐ.βɾɐ̃ˈʒẽ.sjɐ] camping	br=câmping:/ˈkɐ̃.pĩ/ doping	br=dóping:/ˈdɔ.pĩ/ jogging	br=djógguing:/ˈd͡ʒɔ.ɡĩ/ Beijing	:br=/be(j)ˈʒĩ/ Wellington	br=Wéllington:/ˈwɛ.lĩ.tõ/ Washington	br=Wóshington:/ˈwɔ.ʃĩ.tõ/ distinguir	pt=distinguir:[diʃ.tĩˈɡiɾ]	br=distingüir:gbr=[d͡ʒis.t͡ʃĩˈɡwi(h)];rio=[d͡ʒiʃ.t͡ʃĩˈɡwi(χ)];sp=[d͡ʒis.t͡ʃĩˈɡwi(ɾ)] Hungria	:[ũˈɡɾi.ɐ] interrobang	pt=intẹrrobangue:/ĩ.tɛ.ʁuˈbɐ̃.ɡɨ/	br=interrobangue:/ĩ.te.ʁoˈbɐ̃.ɡi/ linguiça	lingu.iça,lingüiça:/lĩ.ɡuˈi.sɐ/,/lĩˈɡwi.sɐ/ long neck	br=lòngh nécke,lòngue nécke:/ˌlõɡ ˈnɛ.ki/,/ˌlõ.ɡi ˈnɛ.ki/ Los Angeles	br=Lộs Ângeles:gbr-sp=/loz ˈɐ̃.ʒe.lis/;rio=/loz ˈɐ̃.ʒe.liʃ/ single	br=síngol:/ˈsĩ.ɡow/ Stonehenge	sp=Stòwnn.rrendj:[ˌstoʊ̯nˈhẽd͡ʒ] viking	br=víking,víkingue:/ˈvi.kĩ/,/ˈvi.kĩ.ɡi/ zângão	:/ˈzɐ̃.ɡɐ̃w̃/
 * ng

banho	:br=/ˈbɐ̃.ɲu/;pt=/ˈbɐ.ɲu/ Congonhinhas	sp=Còngonhinhas:/ˌkõ.ɡõˈɲĩ.ɲɐs/ Congonhinhas	sp=Còngonhinhas:[ˌkõ.ɡõˈj̃ĩ.j̃ɐs] nheengatu	br=nhengatu:/ɲẽ.ɡaˈtu/ ainhum	:br=/ɐ̃j̃ˈɲũ/ rainha	:br=/ʁaˈĩ.ɲɐ/;pt=/ʁɐˈi.ɲɐ/ moinho	br=moinho,muinho:/moˈĩ.ɲu/,/muˈĩ.ɲu/	pt=muinho,mu.inho:/ˈmwi.ɲu/,/muˈi.ɲu/
 * nh

ablaquear	ablaquyar:pt=/ɐ.blɐˈkjaɾ/ acqua alta	:pt=/ˈa.kwɐ ˈal.tɐ/ freqüentemente	:br=/fɾeˌkwẽ.t͡ʃiˈmẽ.t͡ʃi/ obséquio	obzéquyo:br=/obˈzɛ.kju/ quando	:/ˈkwɐ̃.du/ que	:br=/ki/;pt=/kɨ/ quebra-nozes	québra-nózes:pt=[ˈkɛ.βɾɐ ˈnɔ.zɨʃ] qüiproquó	br=qüìproquó:/ˌkwi.pɾoˈkwɔ/
 * q

bilro	:rio=[ˈbiʊ̯.χu];pt=[ˈbiɫ.ʁu];gbr-sp=[ˈbiʊ̯.hu] carro	:rio=[ˈka.χu];pt=[ˈka.ʁu];gbr-sp=[ˈka.hu] genro	:rio=[ˈʒẽ.χu];pt=[ˈʒẽ.ʁu];gbr-sp=[ˈʒẽ.hu] Israel	Israél:pt=[iʒ.ʁɐˈɛɫ];gbr-sp=[iz.haˈɛʊ̯];rio=[iʒ.χaˈɛʊ̯] redor	redór:gbr=[heˈdɔh];rio=[χeˈdɔχ];sp=[heˈdɔɾ] parte	:rio=[ˈpaχ.t͡ʃi];gbr=[ˈpah.t͡ʃi];sp=[ˈpaɾ.t͡ʃi];pt=[ˈpaɾ.tɨ] pardo	:gbr=[ˈpaɦ.du];rio=[ˈpaʁ.du];sp=[ˈpaɾ.du];pt=[ˈpaɾ.ðu];spt=[ˈpaɾ.du] workstation	wồrkstêishon:gbr=/ˌwoʁksˈtej.ʃõ/;rio=/ˌwoʁkʃˈtej.ʃõ/ fazer	fazêr:gbr-rio=/faˈze(ʁ)/;sp=/faˈze(ɾ)/;pt=/fɐˈzeɾ/ fazer a coisa	fazêr a coisa:br=/faˈze(ɾ) a ˈkoj.zɐ/;pt=/fɐˈzeɾ ɐ ˈkoj.zɐ/ pôr	:gbr-rio=/ˈpoʁ/;sp-pt=/ˈpoɾ/ mar	:pt=/ˈmaɾ/	br=marh:gbr-rio=/ˈmaʁ/;sp=/ˈmaɾ/
 * r

cansar	:sp=/kɐ̃ˈsa(ɾ)/;gbr-rio=/kɐ̃ˈsa(ʁ)/ intransigente	:br=/ĩ.tɾɐ̃.ziˈʒẽ.t͡ʃi/;pt=/ĩ.tɾɐ̃.ziˈʒẽ.tɨ/ passo	:/ˈpa.su/ caso	:/ˈka.zu/ mesmo	mêsmo:rio-pt=/ˈmeʒ.mu/;gbr-sp=/ˈmez.mu/ lesma	lêsma:pt=/ˈleʒ.mɐ/ está	:rio=/iʃˈta/;pt=/(i)ʃˈta/;sp=/isˈta/ esbarra	:rio=/iʒˈba.ʁɐ/;pt=/(i)ʒˈba.ʁɐ/;sp=/izˈba.ʁɐ/ os árvores	:rio=/uz ˈaʁ.vo.ɾiʃ/;gbr=/uz ˈaʁ.vo.ɾis/;sp=/uz ˈaɾ.vo.ɾis/;pt=/uz ˈaɾ.vu.ɾɨʃ/ os habitantes	:rio=/uz a.biˈtɐ̃.t͡ʃiʃ/;gbr-sp=/uz a.biˈtɐ̃.t͡ʃis/;pt=/uz ɐ.biˈtɐ̃.tɨʃ/ as gentes	:rio=/a ˈʒẽ.t͡ʃiʃ/;gbr-sp=/az ˈʒẽ.t͡ʃis/;pt=/ɐ ˈʒẽ.tɨʃ/ os sucos	:rio=/u ˈsu.kuʃ/;gbr-sp=/u ˈsu.kus/;pt=/uʃ ˈsu.kuʃ/ os pés	os péss:rio-pt=/uʃ ˈpɛʃ/;gbr-sp=/us ˈpɛs/ nós	:rio=/ˈnɔ(j)ʃ/;gbr-sp=/ˈnɔ(j)s/;pt=/ˈnɔʃ/ nós	nóss:rio-pt=/ˈnɔʃ/;gbr-sp=/ˈnɔs/ nós	nóhs:rio-pt=/ˈnɔʃ/;gbr-sp=/ˈnɔs/ excelente	escelente:br=/e.seˈlẽ.t͡ʃi/ nascimento	:br=/na.siˈmẽ.tu/;pt=/nɐʃ.siˈmẽ.tu/ sueca	suéca:pt=/ˈswɛ.kɐ/ suave	:pt=/ˈswa.vɨ/ stresse	sstrésse:pt=/ˈstɾɛ.sɨ/ stress	sstréç:pt=/ˈstɾɛs/ Donbass	Donbáç:pt=/dõˈbas/
 * s

xérox	:br=/ˈʃɛ.ɾɔks/ baixo	:br=/ˈba(j).ʃu/;pt=/ˈbaj.ʃu/ peixe	:br=/ˈpe(j).ʃi/;cpt=/ˈpej.ʃɨ/;gpt=/ˈpɐj.ʃɨ/;spt=/ˈpe.ʃɨ/ peixe	:br=[ˈpe(ɪ̯).ʃi];cpt=[ˈpej.ʃɨ];gpt=[ˈpɐj.ʃɨ];spt=[ˈpe.ʃɨ] frouxo	:gpt=/ˈfɾo(w).ʃu/ axé	ashé:br=/aˈʃɛ/;pt=/ɐˈʃɛ/
 * x

Itamaraty	:br=/i.ta.ma.ɾaˈt͡ʃi/ Sydney	Sýdjney:br=/ˈsid͡ʒ.nej/
 * y

prazo	:/ˈpɾa.zu/ dez	déz:rio=/ˈdɛ(j)ʃ/;gbr-sp=/ˈdɛ(j)s/;pt=/ˈdɛʃ/ faz	:rio=/ˈfa(j)ʃ/;gbr-sp=/ˈfa(j)s/;pt=/ˈfaʃ/ dez árvores	déz árvores:rio=/ˈdɛ(j)z ˈaʁ.vo.ɾiʃ/;gbr=/ˈdɛ(j)z ˈaʁ.vo.ɾis/;sp=/ˈdɛ(j)z ˈaɾ.vo.ɾis/;pt=/ˈdɛz ˈaɾ.vu.ɾɨʃ/ dez habitantes	déz habitantes:rio=/ˈdɛ(j)z a.biˈtɐ̃.t͡ʃiʃ/;gbr-sp=/ˈdɛ(j)z a.biˈtɐ̃.t͡ʃis/;pt=/ˈdɛz ɐ.biˈtɐ̃.tɨʃ/ dez gentes	déz gentes:rio=/ˈdɛ(j) ˈʒẽ.t͡ʃiʃ/;gbr-sp=/ˈdɛ(j)z ˈʒẽ.t͡ʃis/;pt=/ˈdɛ ˈʒẽ.tɨʃ/ dez sucos	déz sucos:rio=/ˈdɛ(j) ˈsu.kuʃ/;gbr-sp=/ˈdɛ(j) ˈsu.kus/;pt=/ˈdɛʃ ˈsu.kuʃ/ dez pés	déz péss:rio=/ˈdɛ(j)ʃ ˈpɛʃ/;gbr-sp=/ˈdɛ(j)s ˈpɛs/;pt=/ˈdɛʃ ˈpɛʃ/ topázio	:pt=/tuˈpa.zju/ disprósio	:pt=/diʃˈpɾɔ.zju/ césio	:pt=/ˈsɛ.zju/ Ásia	Ásya:pt-rio=/ˈa.zjɐ/ casual	:pt=/kɐˈzwal/ casuar	:pt=/kɐˈzwaɾ/ zoar	zuar:pt=/ˈzwaɾ/
 * z

afortunadamente	:gbr-rio=/a.foʁ.tuˌna.daˈmẽ.t͡ʃi/;sp=/a.foɾ.tuˌna.daˈmẽ.t͡ʃi/;pt=[ɐ.fuɾ.tuˌna.ðɐˈmẽ.tɨ];spt=[ɐ.fuɾ.tuˌna.dɐˈmẽ.tɨ] alertamente	alértamente:gbr-rio=/aˌlɛʁ.taˈmẽ.t͡ʃi/;sp=/aˌlɛɾ.taˈmẽ.t͡ʃi/;pt=/ɐˌlɛɾ.tɐˈmẽ.tɨ/ anticristãmente	:rio=/ɐ̃.t͡ʃi.kɾiʃˌtɐ̃ˈmẽ.t͡ʃi/;gbr-sp=/ɐ̃.t͡ʃi.kɾisˌtɐ̃ˈmẽ.t͡ʃi/;pt=/ɐ̃.ti.kɾiʃˌtɐ̃ˈmẽ.tɨ/ comummente	comum.mente:pt=/kuˌmũˈmẽ.tɨ/ dormente	dormênte:br=/doʁˈmẽ.t͡ʃi/;sp=/doɾˈmẽ.t͡ʃi/;pt=/duɾˈmẽ.tɨ/ posteriormente	posteriôrmente:gbr=/pos.te.ɾiˌoʁˈmẽ.t͡ʃi/;rio=/poʃ.te.ɾiˌoʁˈmẽ.t͡ʃi/;sp=/pos.te.ɾiˌoɾˈmẽ.t͡ʃi/;pt=/puʃ.tɨˌɾjoɾˈmẽ.tɨ/ somente	sómente:br=/ˌsɔˈmẽ.t͡ʃi/;pt=/ˌsɔˈmẽ.tɨ/ simplesmente	:pt=/ˌsĩ.plɨʒˈmẽ.tɨ/;rio=/ˌsĩ.pliʒˈmẽ.t͡ʃi/;gbr-sp=/ˌsĩ.plizˈmẽ.t͡ʃi/
 * 1) -mente

balãozinho	:br=/baˌlɐ̃w̃ˈzĩ.ɲu/ bauzinho	baúzinho:br=/baˌuˈzĩ.ɲu/ coraçãozinho	cồraçãozinho:br=/ˌko.ɾaˌsɐ̃w̃ˈzĩ.ɲu/ finalzinho	:br=/fiˌnawˈzĩ.ɲu/;pt=/fiˌnalˈzi.ɲu/ homenzinho	:br=/ˌõ.mẽj̃ˈzĩ.ɲu/ nenenzinho	nenénzinho:br=/neˌnẽj̃ˈzĩ.ɲu/ pobrezinho	póbrezinho:br=[ˌpɔ.bɾiˈzĩ.j̃u];pt=[ˌpɔ.βɾɨˈzi.ɲu] sozinho	sózinho:br=/ˌsɔˈzĩ.ɲu/;pt=/ˌsɔˈzi.ɲu/ vizinho	br=vizínho:/viˈzĩ.ɲu/	pt=vizínho,vezínho:/viˈzi.ɲu/,/vɨˈzi.ɲu/ -- (This should be a different rule, see https://www.flip.pt/Duvidas-Linguisticas/Duvida-Linguistica/DID/1303)
 * 1) -zinho

Accra	:/ˈa.kɾɐ/ Aleppo	Aléppo:br=/aˈlɛ.pu/ buffer	bâfferh:gbr-rio=/ˈbɐ.feʁ/;sp=/ˈbɐ.feɾ/ cheddar	chéddarh:gbr-rio=/ˈʃɛ.daʁ/;sp=/ˈʃɛ.daɾ/ Hanna	br=Ranna:/ˈʁɐ̃.nɐ/ jazz	djézz:gbr-sp=/ˈd͡ʒɛ(j)s/;rio=/ˈd͡ʒɛ(j)ʃ/ Minnesota	Mìnnessôta:br=/ˌmi.neˈso.tɐ/ nutella	nutélla:/nuˈtɛ.lɐ/ shopping	br=shópping,shóppem:/ˈʃɔ.pĩ/,/ˈʃɔ.pẽj̃/ Yunnan	:br=/juˈnɐ̃/;pt=/juˈnan/
 * 1) double letters

água mole em pedra dura tanto bate até que fura	água móle em pédra dura tanto bate até que fura:br=/ˈa.ɡwɐ ˈmɔ.li ẽj̃ ˈpɛ.dɾɐ ˈdu.ɾɐ ˈtɐ̃.tu ˈba.t͡ʃi aˈtɛ ki ˈfu.ɾɐ/;gpt=[ˈa.ɣwɐ ˈmɔ.l(ɨ) ɐ̃j̃ ˈpɛ.ðɾɐ ˈðu.ɾɐ ˈtɐ̃.tu ˈβa.t(ɨ) ɐ.ˈtɛ kɨ ˈfu.ɾɐ] era só o que me faltava	éra só o que me faltava:br=/ˈɛ.ɾɐ ˈsɔ u ki mi fawˈta.vɐ/
 * 1) multiword expressions

mãe	:/ˈmɐ̃j̃/ mãe	:pt=[ˈmɐ̃j̃];br=[ˈmɐ̃ɪ̯̃] põem	põeem:br-cpt=/ˈpõj̃.ẽj̃/;gpt=/ˈpõj̃.ɐ̃j̃/ pãozão	:/pɐ̃w̃ˈzɐ̃w̃/ Itapoã	:br=/i.ta.poˈɐ̃/
 * 1) nasalized vowels

saiba	:/ˈsaj.bɐ/ saiba	:br=[ˈsaɪ̯.bɐ];pt=[ˈsaj.βɐ] papeis	:gpt=/pɐˈpɐjʃ/;cpt=/pɐˈpejʃ/ papéis	:gpt=/pɐˈpɐjʃ/;cpt=/pɐˈpɛjʃ/ anéis	:gpt=/ɐˈnɐjʃ/ noite	:br=/ˈnoj.t͡ʃi/;pt=/ˈnoj.tɨ/ noite	:br=[ˈnoɪ̯.t͡ʃi] Paulo	:/ˈpaw.lu/ Paulo	:pt=[ˈpaw.lu];br=[ˈpaʊ̯.lu] deusa	:/ˈdew.zɐ/ deusa	:br=[ˈdeʊ̯.zɐ] ouro	:br-pt=/ˈo(w).ɾu/;spt=/ˈo.ɾu/ ouro	:br=[ˈo(ʊ̯).ɾu] sair	:gbr-rio=/saˈi(ʁ)/;sp=/saˈi(ɾ)/;pt=/sɐˈiɾ/ Raul	:br=/ʁaˈuw/;pt=/ʁɐˈul/ queimar	:gbr-rio=/kejˈma(ʁ)/;sp=/kejˈma(ɾ)/;cpt=/kejˈmaɾ/;gpt=/kɐjˈmaɾ/ baile	:br=/ˈbaj.li/;pt=/ˈbaj.lɨ/ beira	:br=/ˈbe(j).ɾɐ/;gpt=/ˈbɐj.ɾɐ/;cpt=/ˈbej.ɾɐ/ saia	:/ˈsaj.ɐ/ saia	:br=[ˈsaɪ̯.ɐ] saiu	:br=/saˈiw/;pt=/sɐˈiw/ saiu	:br=[saˈiʊ̯] saído	:br=/saˈi.du/;pt=/sɐˈi.du/ sinusoidal	sinusòidal:pt=/si.nuˌzɔjˈdal/ asteroidal	asteròidal:pt=/ɐʃ.tɨˌɾɔjˈdal/
 * 1) oral diphthongs

vieira	:br=/viˈe(j).ɾɐ/;gpt=/ˈvjɐj.ɾɐ/;cpt=/ˈvjej.ɾɐ/ ia	:/ˈi.ɐ/ iogurte	br=i.ogurte,iogurte:gbr-rio=/i.oˈɡuʁ.t͡ʃi/,/joˈɡuʁ.t͡ʃi/;sp=/i.oˈɡuɾ.t͡ʃi/,/joˈɡuɾ.t͡ʃi/	pt=iọgurte:/jɔˈɡuɾ.tɨ/ ]]
 * 1) hiatus

function tests:check_ipa(spelling, expected, comment) local inputs = {} for style, expected_obj in pairs(expected) do		inputs[style] = expected_obj.respellings end

local expressed_styles = m_pt_pronunc.express_styles(inputs) for _, style_group in ipairs(expressed_styles) do		for _, style_obj in ipairs(style_group.styles) do options.comment = style_obj.tag and style_obj.tag .. (comment and "; " .. comment or "") or comment or ""

local function get_actual_ipas(ipa_type) local actual_ipas = {} for _, phonemic_phonetic in ipairs(style_obj.phonemic_phonetic) do					local ipa = phonemic_phonetic[ipa_type] if ipa_type == "phonemic" then ipa = "/" .. ipa .. "/"					else ipa = "[" .. ipa .. "]"					end table.insert(actual_ipas, ipa) end return table.concat(actual_ipas, ",") end

-- Check if all the styles represented by this particular actual IPA have the same expected IPA. -- If so, we can display a single test line (whether or not the actual and expected match). -- Otherwise, display each style individually. local matches = true local matching_respellings = nil local matching_expected_ipas = nil local matching_ipa_type = nil

for _, represented_style in ipairs(style_obj.represented_styles) do				if not expected[represented_style] then error("Internal error: Didn't generate IPA for style '" .. represented_style .. "'") end local this_respellings = table.concat(expected[represented_style].respellings, ",") local this_expected_ipas = table.concat(expected[represented_style].ipas, ",") local this_ipa_type = expected[represented_style].type if not matching_expected_ipas then matching_respellings = this_respellings matching_expected_ipas = this_expected_ipas matching_ipa_type = this_ipa_type elseif matching_respellings ~= this_respellings or matching_expected_ipas ~= this_expected_ipas or					matching_ipa_type ~= this_ipa_type then matches = false break end end

if matches then self:equals(					link(spelling) .. (matching_respellings == spelling and "" or ", respelled " .. matching_respellings),					get_actual_ipas(matching_ipa_type),					matching_expected_ipas,					options				) else for _, represented_style in ipairs(style_obj.represented_styles) do					if not expected[represented_style] then error("Internal error: Didn't generate IPA for style '" .. represented_style .. "'") end local this_respellings = table.concat(expected[represented_style].respellings, ",") local this_expected_ipas = table.concat(expected[represented_style].ipas, ",") local this_ipa_type = expected[represented_style].type options.comment = m_pt_pronunc.all_style_descs[represented_style] .. (comment and "; " .. comment or "") self:equals(						link(spelling) .. (this_respellings == spelling and "" or ", respelled " .. this_respellings),						get_actual_ipas(this_ipa_type),						this_expected_ipas,						options					) end end end end end

local function parse(examples) -- The following is a list of parsed examples where each element is a three-element list of -- {SPELLING, EXPECTED, COMMENT}. SPELLING is the actual spelling of the term; EXPECTED is a table giving -- the respellings and associated expected IPA, and COMMENT is an optional comment (if given starting with a	-- # sign after a given line) or nil. EXPECTED is a table whose keys are basic styles, e.g. "rio", "lisbon", -- and values are a table with keys 'respellings' (one or more respellings), 'ipas' (corresponding IPA values) -- and 'type' ("phonemic" or "phonetic"). local parsed_examples = {} -- Throw away comments starting with -- and snarf each line. for line in examples:gsub("%s*%-%-[^\n]*", ""):gmatch "[^\n]+" do -- Trim whitespace at beginning and end. line = line:gsub("^%s*(.-)%s*$", "%1") if line ~= "" then -- skip blank lines local function err(msg) error(msg .. ": " .. line) end local function rsplit2(term, regex) local splitvals = rsplit(term, regex) if #splitvals ~= 2 then err("Expected two parts in '" .. term .. "' when split by '" .. regex .. "'") end return splitvals end if line:find("^#") then -- Line beginning with # is a section header. line = line:gsub("^#%s*", "") table.insert(parsed_examples, line) else local function expand_styles(styles) local expansion = {} for _, style in ipairs(rsplit(styles, "%-")) do						if all_style_set[style] then table.insert(expansion, style) elseif m_pt_pronunc.all_style_groups[style] then for _, basic in ipairs(m_pt_pronunc.all_style_groups[style]) do								table.insert(expansion, basic) end else err("Unrecognized style '" .. style .. "'") end end return expansion end

local parts = rsplit(line, "\t") local spelling = parts[1] local expected = {} local comment for i=2,#parts do					local part = parts[i] if part:find("^#") then if i ~= #parts then err("Comment .. " .. part .. " should be last element on the line") end comment = part break end local respelling, styled_ipas = unpack(rsplit2(part, ":")) local styles if respelling:find("=") then styles, respelling = unpack(rsplit2(respelling, "=")) else styles = "all" end if respelling == "" then respelling = spelling end respelling = rsplit(respelling, ",") styles = expand_styles(styles) local style_set = m_table.listToSet(styles) for _, styled_ipa in ipairs(rsplit(styled_ipas, ";")) do						local ipa_styles, ipas if styled_ipa:find("=") then ipa_styles, ipas = unpack(rsplit2(styled_ipa, "=")) ipa_styles = expand_styles(ipa_styles) else ipa_styles = styles ipas = styled_ipa end ipas = rsplit(ipas, ",") local ipa_type for _, ipa in ipairs(ipas) do							local this_ipa_type if ipa:find("^/.*/$") then this_ipa_type = "phonemic" elseif ipa:find("^%[.*%]$") then this_ipa_type = "phonetic" else err("IPA " .. ipa .. " should be surrounded with /.../ or [...]") end if not ipa_type then ipa_type = this_ipa_type elseif ipa_type ~= this_ipa_type then err("All IPA values " .. table.concat(ipa, ",") ..									" specified for this style should agree in being phonemic or phonetic") end end for _, ipa_style in ipairs(ipa_styles) do							if not style_set[ipa_style] then err("Style '" .. ipa_style .. "' not listed among respelling styles " ..									table.concat(styles, ",")) end expected[ipa_style] = {respellings = respelling, ipas = ipas, type = ipa_type} end end end if not next(expected) then err("No expected pronunciations given") end table.insert(parsed_examples, {spelling, expected, comment}) end end end return parsed_examples end

function tests:test self:iterate(parse(examples), "check_ipa") end

return tests