Vikisözlük trwiktionary https://tr.wiktionary.org/wiki/Vikis%C3%B6zl%C3%BCk:Anasayfa MediaWiki 1.47.0-wmf.8 case-sensitive Ortam Özel Tartışma Kullanıcı Kullanıcı mesaj Vikisözlük Vikisözlük tartışma Dosya Dosya tartışma MediaWiki MediaWiki tartışma Şablon Şablon tartışma Yardım Yardım tartışma Kategori Kategori tartışma Portal Portal tartışma YeniKurum YeniKurum tartışma Ek Ek tartışma Alıntılar Alıntılar tartışma TimedText TimedText talk Modül Modül tartışma Event Event talk anahtar 0 6663 5672659 5253839 2026-06-29T22:36:56Z Satirdan kahraman 37401 TurkceMaddePanel 5672659 wikitext text/x-wiki {{Haftanın kelimesi|2|2007}} ==Türkçe== ===Köken=== *{{k|dil=tr|ota}} {{z|ota|آنهار|anlam=anahtar}}. O da {{köken|dil=tr|el}} {{b|el|ανοιχτήριον|ç=aniχtíri(on)||açkı, açacak}} sözcüğünden alıntıdır. Bu sözcük {{b|grc|ανοίγω|ç=anoígō, ánoíksis||açmak}} fiilinden +ion ekiyle türetilmiştir. Eski Yunanca fiil {{b|grc|οίγω|ç=oígō||açmak}} fiilinden ana+ önekiyle türetilmiştir. ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||a|nah|tar}} ===Ad=== {{tr-ad}} [[resim:Diverse sleutels.jpg|küçükresim|300 px|{{mânâ|kilit açar}} Muhtelif '''anahtarlar''' (1)]] # {{t|dil=tr|aletler}} Kilidi açıp kapamak için kullanılan araç; [[açacak]], [[açar]], [[açkı]], [[miftah]], [[dil]] # [[kurgu]]. # {{t|dil=tr|iletişim}}Şifre yazmak ve çözmek için kararlaştırılmış olan yol. # {{t|dil=tr|aletler}} Somunları veya vidaları çevirerek sıkıştırıp gevşetmek için kullanılan çelik saplı araç. # {{t|dil=tr|aletler}} Konserve kutularının kapağını keserek açmaya yarayan alet; [[açacak]]. # {{t|dil=tr|elektrik}} İİstenilen yere veya aygıta, isteğe göre elektrik akımının geçmesini sağlamak için kullanılan düzen; [[çevirici]], [[çevirgeç]], [[şalter]], [[komütatör]] # {{t|dil=tr|müzik}} Notaların müzik merdivenindeki yükseklik derecelerini göstermek ve buna göre okunmasını sağlamak için portenin başına konulan işaret. # {{t|dil=tr|müzik}} Piyano, ut, kanun gibi çalgılarda ayar aleti. #{{t|dil=tr|argo|suç}} [[rüşvet]]. # {{t|dil=tr|eğitim}} {{kısa|tr|cevap anahtarı}} ====Çekimleme==== {{tr-ad-tablo}} ===Ön ad=== {{tr-ön ad}} #{{t|dil=tr|mecaz }} Herhangi bir olayda belirleyici olan. #* Anahtar parti. ====Deyimler==== [[anahtarı beline takmak]], [[anahtar uydurmak]], [[anahtar vermek]] ====Türetilmiş kavramlar==== [[anahtar ağızlığı]], [[anahtar bitkiler]], [[anahtar deliği]], [[anahtar dili]], [[anahtar dişi]], [[anahtar kelime]], [[anahtar kovanı]], [[anahtar sözcük]], [[anahtar taşı]], [[erkek anahtar]], [[kovan anahtar]], [[lokma anahtar]], [[alyan anahtarı]], [[basınç anahtarı]], [[bijon anahtarı]], [[cevap anahtarı]], [[do anahtarı]], [[elektrik anahtarı]], [[fa anahtarı]], [[hırsız anahtarı]], [[İngiliz anahtarı]], [[kontak anahtarı]], [[papağan anahtarı]], [[sol anahtarı]], [[şifre anahtarı]], [[tavşan anahtarı]] ====Çeviriler==== {{Üst|tip=çeviriler}} *Afrikanca: {{ç|af|}} *Almanca: {{ç|de|Schlüssel|m}} *Arapça: {{ç|ar|مِفْتَاح|m}}, {{ç|ar|مِقْلَاد|e}} *Arnavutça: {{ç|sq|}} *Azerice: {{ç|az|açar}} *Baskça: {{ç|eu|}} *Başkurtça: {{ç|ba|}} *Bretonca: {{ç|br|}} *Bulgarca: {{ç|bg|}} *Çekçe: {{ç|cs|}} *Danca: {{ç|da|nøgle}} *Endonezce: {{ç|id|}} *Estonca: {{ç|et|võti}} *Felemenkçe: {{ç|nl|sleutel|m}} *Fince: {{ç|fi|avain}}, {{ç|fi|kommutaattori}}, {{ç|fi|kytkin}} *Fransızca: {{ç|fr|clé|f}}, {{ç|fr|clef|f}}, {{ç|fr|commutateur}} *Gagavuzca: {{ç|gag|}} *Gürcüce: {{ç|ka|}} *İngilizce: {{ç|en|key}} *İspanyolca: {{ç|es|}} *İsveççe: {{ç|sv|}} *İtalyanca: {{ç|it|}} *İzlandaca: {{ç|is|}} *Karaçay-Balkarca: {{ç|krc|açhıç}} *Kazakça: {{ç|kk|кілт}} *Kırgızca: {{ç|ky|ачқе}}*Katalanca: {{ç|ca|}} *Kırım Tatarcası: {{ç|crh|anahtar}} *Lehçe: {{ç|pl|klucz}} *Marathi dili: {{ç|mr|चावी}} *Mokşa dili: {{ç|mdf|панжема}} *Norveççe: {{ç|no|}} *Osmanlı Türkçesi: {{ç|ota|آنهار}} *Özbekçe: {{ç|uz|калит}} *Portekizce: {{ç|pt|}} *Rumence: {{ç|ro|}} *Rusça: {{ç|ru|}} *Slovakça: {{ç|sk|}} *Slovence: {{ç|sl|}} *Somalice: {{ç|so|fure magac}} *Tabasaran dili: {{ç|tab|}} *Tacikçe: {{ç|tg|}} *Tatarca: {{ç|tt|açkıç}}, {{ç|tt|açqıç}} *Türkmence: {{ç|tk|ачар}}, {{ç|tk|açar}} *Uygurca: {{ç|ug|ئاچقۇچ}} *Ukraynaca: {{ç|uk|}} *Yunanca: {{ç|el|}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} ==Kırım Tatarcası== ===Söyleniş=== * {{h|dil=crh||a|nah|tar}} ===Ad=== {{başlık başı|crh|ad}} # {{t|dil=crh|aletler}} {{b|tr|anahtar}} 9n31x7rzvmdl25bglcf2lnr4m1fcijc Yılmaz 0 42132 5672513 5254748 2026-06-29T17:50:29Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672513 wikitext text/x-wiki {{bakınız|yılmaz}} ==Türkçe== ===Özel ad=== {{tr-özel ad|k=1}} {{tr-ad}} # {{t|dil=tr|beldeler}} [[Manisa]] ili [[Salihli]] ilçesine bağlı belde # {{özel ad|dil=tr|erkek adı}} [[erkek]] adı # {{t|dil=tr|köyler}} [[Mardin]] ili [[Dargeçit]] ilçesine bağlı [[köy]] # {{özel ad|dil=tr|soyadı}} [[soyadı]] ====Söyleniş==== * {{IPA|dil=tr|j/ɯlˈmaz/|ç=/jɯlmazˈlaɾ/}} * {{h|dil=tr|a|Yıl|maz|k=1}} ===Köken=== {{köken|dil=tr|tr}} yılmaz ===Kaynakça=== * {{proje bağlantısı|vikipedi|{{PAGENAME}}, Dargeçit}} * {{Yurtsever-TAD-1997}} 4afkviynwfhat3yym90l720tj3k29b1 çizgili 0 48926 5672715 4865849 2026-06-30T06:18:19Z Satirdan kahraman 37401 TurkceMaddePanel 5672715 wikitext text/x-wiki ==Türkçe== ====Köken==== {{ek|dil=tr|çizgi|li}} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||çiz|gi|li}} ===Ön ad=== {{tr-ön ad}} [[File:Striped hyena in Bhigwan August 2025 by Tisha Mukherjee 12.jpg|küçükresim|'''Çizgili''' sırtlan ]] # Üzerinde çizgi bulunan ====Çeviriler==== {{üst|tip=çeviriler}} *İngilizce: {{ç|en|striped}} *Kırım Tatarca: {{ç|crh|çizgili}}, {{ç|crh|yolaqlı}} {{alt}} ===Kaynakça=== * {{KYK:TDK}} ==Kırım Tatarca== ===Ön ad=== {{başlık başı|crh|ön ad}} # çizgili 76s1w6xqtvujwsp768lnrtrpow49vz4 katı 0 52344 5672713 5343508 2026-06-30T06:16:51Z Satirdan kahraman 37401 TurkceMaddePanel 5672713 wikitext text/x-wiki {{bakınız|kat'î|kati}} ==Türkçe== ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||ka|tı}} ===Ön ad=== {{tr-ön ad}} [[File:Smoky quartz 15.jpg|küçükresim|{{mana|ön ad}} Bu taş çok '''katı''' (1) Taş, maddenin katı hâlinde. (4)]] # sert, [[yumuşak]] karşıtı. #*Bu hâl, onu ilk defa giyilen katı gömlek gibi sıkıyordu." - Falih Rıfkı Atay # {{t|dil=tr|mecaz}}Hoşgörüsüz, acımasız, merhametsiz, zalim olan. #* Katı yürekli. Katı davranış. # {{t|dil=tr|mecaz}} Düşünce ve davranışlarında belli ilkelere sıkı sıkıya bağlı olan, hoşgörüsü olmayan; [[sıkı]]. # {{t|dil=tr|fizik}}Sıvıların ve gazların tersine, içinde bulunduğu kabın veya üstünde bulunduğu yerin biçimini almayan; [[sulp]]. # {{t|dil=tr|anatomi}} [[taşlık]] ====Sözcük birliktelikleri==== [[katı atık]], [[katı kalpli]], [[katı sabun]], [[katı söz]], [[katı yağ]], [[katı yumurta]], [[katı yürekli]], [[yüreği katı]] ===Belirteç=== {{tr-belirteç}} # {{t|dil=tr|eskimiş}} Çok, aşırı derecede. #* "Susadım ol dem hararetten katı / Sundular bir cam dolusu şerbeti" - Süleyman Çelebi ===Ad=== {{başlık başı|tr|çekimli ad}} # {{tr-çekim|kat|söz=ad}} ====Çeviriler==== {{Üst|anatomi|tip=çeviriler}} * Danca: {{ç|da|muskelmave}} * Fince: {{ç|fi|kiinteä olomuoto}}, {{ç|fi|kivipiira}}, {{ç|fi|lihasmaha}} * Fransızca: {{ç|fr|gésier|m}} * İngilizce: {{ç|en|gizzard}} * İsveççe: {{ç|sv|muskelmage}} * Kürtçe: {{ç|ku|req}} * Macarca: {{ç|hu|zúza}} {{Alt}} ===Ek okumalar=== * {{proje bağlantısı|Vikipedi}} ====Çeviriler==== {{Üst|belirteç|tip=çeviriler}} * Almanca: {{ç|de|fest}} * Fince: {{ç|fi|kovin}} {{Alt}} ====Çeviriler==== {{Üst|fizik|tip=çeviriler}} * Almanca: {{ç|de|fest}} * Azerice: {{ç|az|bərk}}, {{ç|az|möhkəm}} * Çekçe: {{ç|cs|pevný}} * Fince: {{ç|fi|kova}}, {{ç|fi|jähmeä}}, {{ç|fi|kiinteä}}, {{ç|fi|luja}} * İngilizce: {{ç|en|solid}} * Fransızca: {{ç|fr|solide}} * İsveççe: {{ç|sv|fast}} * Kırgızca: {{ç|ky|katuu}} * Portekizce: {{ç|pt|sólido}} * Rumence: {{ç|ro|fix}} * Rusça: {{ç|ru|твёрдый}}, {{ç|ru|жёсткий}} * Türkçe: *: Eski Türkçe: {{ç|otk|katgı}}, {{ç|otk|katıg}}, {{ç|otk|kurç}}, {{ç|otk|tıgramak}} * Vietnamca: {{ç|vi|chắc}} * Yunanca: *: Modern Yunanca: {{ç|el|στερεός}} {{Alt}} ===Kaynakça=== * {{Kaynak-TDK}} ==Karaçay-Balkarca== {{düzenle|alfabe=Karaçay-Balkarca}} ===Ön ad=== {{başlık başı|krc|ön ad}} # [[kuvvetli]] # [[sağlam]] # [[sert]] ==Kumanca== ===Söyleniş=== * {{h|dil=qwm||ka|tı}} ===Ön ad=== {{başlık başı|qwm|ön ad}} # [[kuvvetli]] # [[sağlam]] f6ueyhyw38guhb29zsame7sh5cizvm6 5672714 5672713 2026-06-30T06:17:30Z Satirdan kahraman 37401 TurkceMaddePanel 5672714 wikitext text/x-wiki {{bakınız|kat'î|kati}} ==Türkçe== ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||ka|tı}} ===Ön ad=== {{tr-ön ad}} [[File:Smoky quartz 15.jpg|küçükresim|{{mana|ön ad}} Bu taş çok '''katı''' (1) Taş, maddenin katı hâlinde. (4)]] # sert, [[yumuşak]] karşıtı. #*Bu hâl, onu ilk defa giyilen katı gömlek gibi sıkıyordu." - Falih Rıfkı Atay # {{t|dil=tr|mecaz}}Hoşgörüsüz, acımasız, merhametsiz, zalim olan. #* Katı yürekli. Katı davranış. # {{t|dil=tr|mecaz}} Düşünce ve davranışlarında belli ilkelere sıkı sıkıya bağlı olan, hoşgörüsü olmayan; [[sıkı]]. # {{t|dil=tr|fizik}}Sıvıların ve gazların tersine, içinde bulunduğu kabın veya üstünde bulunduğu yerin biçimini almayan; [[sulp]]. # {{t|dil=tr|anatomi}} [[taşlık]] ====Türetilmiş kavramlar==== [[katı atık]], [[katı kalpli]], [[katı sabun]], [[katı söz]], [[katı yağ]], [[katı yumurta]], [[katı yürekli]], [[yüreği katı]] ===Belirteç=== {{tr-belirteç}} # {{t|dil=tr|eskimiş}} Çok, aşırı derecede. #* "Susadım ol dem hararetten katı / Sundular bir cam dolusu şerbeti" - Süleyman Çelebi ===Ad=== {{başlık başı|tr|çekimli ad}} # {{tr-çekim|kat|söz=ad}} ====Çeviriler==== {{Üst|anatomi|tip=çeviriler}} * Danca: {{ç|da|muskelmave}} * Fince: {{ç|fi|kiinteä olomuoto}}, {{ç|fi|kivipiira}}, {{ç|fi|lihasmaha}} * Fransızca: {{ç|fr|gésier|m}} * İngilizce: {{ç|en|gizzard}} * İsveççe: {{ç|sv|muskelmage}} * Kürtçe: {{ç|ku|req}} * Macarca: {{ç|hu|zúza}} {{Alt}} {{Üst|belirteç|tip=çeviriler}} * Almanca: {{ç|de|fest}} * Fince: {{ç|fi|kovin}} {{Alt}} {{Üst|fizik|tip=çeviriler}} * Almanca: {{ç|de|fest}} * Azerice: {{ç|az|bərk}}, {{ç|az|möhkəm}} * Çekçe: {{ç|cs|pevný}} * Fince: {{ç|fi|kova}}, {{ç|fi|jähmeä}}, {{ç|fi|kiinteä}}, {{ç|fi|luja}} * İngilizce: {{ç|en|solid}} * Fransızca: {{ç|fr|solide}} * İsveççe: {{ç|sv|fast}} * Kırgızca: {{ç|ky|katuu}} * Portekizce: {{ç|pt|sólido}} * Rumence: {{ç|ro|fix}} * Rusça: {{ç|ru|твёрдый}}, {{ç|ru|жёсткий}} * Türkçe: *: Eski Türkçe: {{ç|otk|katgı}}, {{ç|otk|katıg}}, {{ç|otk|kurç}}, {{ç|otk|tıgramak}} * Vietnamca: {{ç|vi|chắc}} * Yunanca: *: Modern Yunanca: {{ç|el|στερεός}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} ==Karaçay-Balkarca== {{düzenle|alfabe=Karaçay-Balkarca}} ===Ön ad=== {{başlık başı|krc|ön ad}} # [[kuvvetli]] # [[sağlam]] # [[sert]] ==Kumanca== ===Söyleniş=== * {{h|dil=qwm||ka|tı}} ===Ön ad=== {{başlık başı|qwm|ön ad}} # [[kuvvetli]] # [[sağlam]] aqg3mo6sq8uuiwzfnahwzuobn6huru6 marşandiz 0 53482 5672527 5635170 2026-06-29T19:17:19Z Satirdan kahraman 37401 TurkceMaddePanel 5672527 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|fr}} {{b|fr|marchandise|anlam=ticari eşya, kargo}} sözcüğünden. Bu sözcük Fransızca {{b|fr|marchand|anlam=tüccar}} sözcüğünden türetilmiştir. Fransızca sözcük Latince aynı anlama gelen {{b|la|mercāns, mercant-}} sözcüğünden evrilmiştir. Bu sözcük Latince {{b|la|mercari|anlam=alıp satmak}} fiilinden {{b|la|+ent}} ekiyle türetilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||mar|şan|diz}} ===Ad=== {{tr-ad}} [[File:TCDD DE 33 075 Konak - Murat.jpg|küçükresim|Bir '''marşandiz.''']] #{{t|dil=tr}} [[yük treni]]. #*{{kt|başlık=Yarım Kalan Yürüyüş|yazar=Mehmet EROĞLU|yayıncı=İletişim Yayınları|yıl=2020|sayfa=57|tanıklık=Peron boş, ileride, ikinci hatta yorgun bir '''marşandiz''', banliyö trenini bekliyor.|dil=tr}} ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== ====Türetilmiş kavramlar==== ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} rtaaxn12qx05be8crz5am7v7g9kvww6 5672528 5672527 2026-06-29T19:18:00Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672528 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|fr}} {{b|fr|marchandise|anlam=ticari eşya, kargo}} sözcüğünden. Bu sözcük Fransızca {{b|fr|marchand|anlam=tüccar}} sözcüğünden türetilmiştir. Fransızca sözcük Latince aynı anlama gelen {{b|la|mercāns, mercant-}} sözcüğünden evrilmiştir. Bu sözcük Latince {{b|la|mercari|anlam=alıp satmak}} fiilinden {{b|la|+ent}} ekiyle türetilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||mar|şan|diz}} ===Ad=== {{tr-ad}} [[File:TCDD DE 33 075 Konak - Murat.jpg|küçükresim|Bir '''marşandiz.''']] #{{t|dil=tr|demiryolu taşıtları}} [[yük treni]]. #*{{kt|başlık=Yarım Kalan Yürüyüş|yazar=Mehmet EROĞLU|yayıncı=İletişim Yayınları|yıl=2020|sayfa=57|tanıklık=Peron boş, ileride, ikinci hatta yorgun bir '''marşandiz''', banliyö trenini bekliyor.|dil=tr}} ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== ====Türetilmiş kavramlar==== ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} e9skmb7fmdj121me39aebgpr90dizb7 5672529 5672528 2026-06-29T19:18:06Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672529 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|fr}} {{b|fr|marchandise|anlam=ticari eşya, kargo}} sözcüğünden. Bu sözcük Fransızca {{b|fr|marchand|anlam=tüccar}} sözcüğünden türetilmiştir. Fransızca sözcük Latince aynı anlama gelen {{b|la|mercāns, mercant-}} sözcüğünden evrilmiştir. Bu sözcük Latince {{b|la|mercari|anlam=alıp satmak}} fiilinden {{b|la|+ent}} ekiyle türetilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||mar|şan|diz}} ===Ad=== {{tr-ad}} [[File:TCDD DE 33 075 Konak - Murat.jpg|küçükresim|Bir '''marşandiz.''']] #{{t|dil=tr|demiryolu taşıtları}} [[yük treni]]. #*{{kt|başlık=Yarım Kalan Yürüyüş|yazar=Mehmet EROĞLU|yayıncı=İletişim Yayınları|yıl=2020|sayfa=57|tanıklık=Peron boş, ileride, ikinci hatta yorgun bir '''marşandiz''', banliyö trenini bekliyor.|dil=tr}} ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} le7bwu7iiwk3y9wcyou7svuq6x9e5z4 nişan halkası 0 54666 5672629 4415692 2026-06-29T22:15:31Z Satirdan kahraman 37401 TurkceMaddePanel 5672629 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|nişan|halka}} ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||ni|şan|hal|ka|sı}} ===Ad=== {{tr-ad}} [[File:Engagement rings.JPG|küçükresim|'''Nişan halkası''' takan bir çift.]] #{{t|dil=tr|takılar|evlilik}} [[nişan yüzüğü]]. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} rpr2ltsl4wudh74bka416bznr9mkg18 5672630 5672629 2026-06-29T22:15:44Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672630 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|nişan|halka}} ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||ni|şan|hal|ka|sı}} ===Ad=== {{tr-ad}} [[File:Engagement rings.JPG|küçükresim|'''Nişan halkası''' takan bir çift.]] #{{t|dil=tr|takılar|evlilik|sembol adları}} [[nişan yüzüğü]]. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} 02k792h3why55zoztfkilkw7fiwr3qt suikastçı 0 56363 5672553 5258285 2026-06-29T20:03:47Z Satirdan kahraman 37401 TurkceMaddePanel 5672553 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{ek|dil=tr|suikast|çı}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||su|i|kast|çı}} ===Ad=== {{tr-ad}} [[File:DC-1914-27-d-Sarajevo-cropped.jpg|küçükresim|Tablodaki '''suikastçı''' siyah giyinmiş ve elinde tabanca var.]] #{{t|dil=tr|suç}} Suikast yapan kimse. ====Çekimleme==== {{tr-ad-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *İngilizce: {{ç|en|assassin}} *Almanca: {{ç|de|Meuchelmörder}} *İngilizce: {{ç|en|assassin‎}} *Fransızca: {{ç|fr|assassin‎}} * Macarca: {{ç|hu|merénylő}} {{alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} 2yvg1vglcpml5kfkjqyic1h5lht6cky yalın ayak 0 57777 5672722 4910084 2026-06-30T07:21:43Z Satirdan kahraman 37401 TurkceMaddePanel 5672722 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|yalın|ayak }} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||ya|lın|a|yak}} ===Ön ad=== {{başlık başı|tr|ön ad}} # Ayakları çıplak. [[File:Barefoot girl3.jpg|küçükresim|{{mana|ön ad}} Bankta, '''yalın ayak''' bir kadın oturuyor. <p> {{mana|belirteç}} Kadın, banka '''yalın ayak''' oturmuş.]] #*'Soldan dört ayak üzerinde, yalın ayak, başı kabak bir adam görülür.'' - N. F. Kısakürek ===Belirteç=== {{tr-belirteç}} # Çıplak ayakla #*''Sonra kalktım, yalın ayak, örtüsüz tahta masaya gittim.'' - H. E. Adıvar ====Çeviriler==== {{Üst|belirteç|tip=çeviriler}} *Fince: {{ç|fi|paljain jaloin}}, {{ç|fi|paljasjaloin}}, {{ç|fi|avojaloin}} *Özbekçe: {{ç|uz|yalan oyoq}}, {{ç|uz|yalangoyoq}} {{Alt}} {{Üst|ön ad|tip=çeviriler}} *Fince: {{ç|fi|paljasjalkainen}} {{Alt}} ====Kaynakça==== *{{kaynak-TDK}} 1amcrldkpzf8qxfd1mycdndgnvxnw1o yorumlama 0 58163 5672542 4327603 2026-06-29T19:36:34Z Satirdan kahraman 37401 TurkceMaddePanel 5672542 wikitext text/x-wiki {{bakınız|yorum}} ==Türkçe== ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||yo|rum|la|ma}} ===Ad=== {{tr-ad}} [[File:Olaus Magnus - On the Art of Prophecy.jpg|thumb|Kral, adamın ölü balıkları '''yorumlamasını''' dinliyor.]] # [[yorumlamak]] işi; [[tefsir]] ====Çekimleme==== {{tr-ad-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *Fince: {{ç|fi|tulkitseminen}} *İngilizce: {{ç|en|interpretation}} Kürtçe: {{ç|ku|şîrovekirin}} {{alt}} ===Kaynakça=== * {{KYK:TDK}} kqbx9gmwxqoh9gtq9pzfnlhcmtzkhay yük katarı 0 58214 5672526 4328155 2026-06-29T19:15:49Z Satirdan kahraman 37401 TurkceMaddePanel 5672526 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|yük|katar}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||yük|ka|ta|rı}} ===Ad=== {{tr-ad}} [[File:TCDD DE 33 075 Konak - Murat.jpg|küçükresim|Bir yük katarı.]] #{{t|dil=tr|demiryolu taşıtları}} [[yük treni]]. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} jv0enoxd6jwthvhfrdjcjviohmpv5zg peron 0 67328 5672530 5259451 2026-06-29T19:22:37Z Satirdan kahraman 37401 TurkceMaddePanel 5672530 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|fr}} {{b|fr|perron|anlam=1. binek taşı, 2. trene biniş platformu}} sözcüğünden. Bu sözcük Fransızca {{b|fr|pierre|anlam=taş}} sözcüğünden {{b|fr|+on}} ekiyle türetilmiştir. Fransızca sözcük Latince {{b|la|petra|anlam=taş}} sözcüğünden evrilmiştir. Bu sözcük Eski Yunanca {{b|grc|πέτρα|ç=pétra|anlam=taş}} sözcüğünden alıntıdır. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||pe|ron}} ===Ad=== {{tr-ad}} [[File:Izmir Coach Terminal 5932.jpg|küçükresim|Otobüs, '''peronda''' bekliyor. (1)]] [[File:Alamnagar Railway Station.jpg|küçükresim|Peron (2).]] # {{t|dil=tr|kara ulaşımı}} Otobüs terminallerinde aracın yanaştığı, yolcuların inip binmesine yarayan bölüm. # {{t|dil=tr|demiryolu ulaşımı}} Tren, tramvay, metro istasyonlarında yol boyunca uzanan, inilip binilen özel bölüm. #* "Peronla yolcu vagonlarını ayıran parmaklığın otomatik demiri kapanıyordu." - Sait Faik Abasıyanık ====Çekimleme==== {{tr-ad-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *Türkmence: {{ç|tk|perron}} {{alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Nişanyan}} jnioe9dr7ekrario09a07dfvdpuvfo7 suikast 0 69317 5672551 5659823 2026-06-29T19:56:15Z Satirdan kahraman 37401 TurkceMaddePanel 5672551 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|sui|kast}} Arapça √swˀ kökünden gelen sūˀ سؤ “kötülük, fenalık, habaset” ve Arapça ḳaṣd قصد “kasıt, maksat” sözcüklerinin bileşiğidir. Daha fazla bilgi için [sui+](/kelime/sui%2B) ve [kasıt](/kelime/kas%C4%B1t) maddelerine bakınız. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||su|i|kast}} ===Ad=== [[File:DC-1914-27-d-Sarajevo-cropped.jpg|küçükresim|Bir suikasti anlatan tablo. (2)]] {{tr-ad|istisna=incelme}} #{{t|dil=tr|cinayet}} Gizlice cana kıyma ve kötülük etmeye kalkışma. #* "Bir nefes alayım derken iğrenç bir suikasta uğradım." - Sait Faik Abasıyanık # Bir devlet büyüğünü veya önemli bir kişiyi plan kurarak öldürme. ====Çekimleme==== {{tr-ad-tablo|istisna=incelme}} ====Deyimler==== * [[suikastta parmağı olmak]] ====Çeviriler==== {{Üst|suikast|tip=çeviriler}} * Almanca: {{ç|de|ْAttentat|n}} * Azerice: {{ç|az|sui-qəsd}} * Arapça: {{ç|ar|ْصُوءِقَصْد|m}} * Fransızca: {{ç|fr|complot|e}}, {{ç|fr|conjuration|d}}, {{ç|fr|assassinat|e}} * İngilizce: {{ç|en|assassination}} * Macarca: {{ç|hu|merénylet}} * Türkçe: *: Osmanlı Türkçesi: {{ç|ota|صوءقصد}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Nişanyan}} ===Ek okumalar=== * {{proje bağlantısı|dil=tr|Vikipedi}} qe07nv80672lmu0g83v44i1qei80v4h 5672552 5672551 2026-06-29T20:01:07Z Satirdan kahraman 37401 TurkceMaddePanel 5672552 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|otk}} {{b|ar|سوء قصد|}}. O da Arapça {{b|ar|سؤ||anlam=kötülük, fenalık, habaset}} ve Arapça {{b|ar|قصد ||anlam=kasıt, maksat}} sözcüklerinin birleşimidir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||su|i|kast}} ===Ad=== [[File:DC-1914-27-d-Sarajevo-cropped.jpg|küçükresim|Bir suikasti anlatan tablo. (2)]] {{tr-ad|istisna=incelme}} #{{t|dil=tr|cinayet}} Gizlice cana kıyma ve kötülük etmeye kalkışma. #* "Bir nefes alayım derken iğrenç bir suikasta uğradım." - Sait Faik Abasıyanık # Bir devlet büyüğünü veya önemli bir kişiyi plan kurarak öldürme. ====Çekimleme==== {{tr-ad-tablo|istisna=incelme}} ====Deyimler==== * [[suikastta parmağı olmak]] ====Çeviriler==== {{Üst|suikast|tip=çeviriler}} * Almanca: {{ç|de|ْAttentat|n}} * Azerice: {{ç|az|sui-qəsd}} * Arapça: {{ç|ar|ْصُوءِقَصْد|m}} * Fransızca: {{ç|fr|complot|e}}, {{ç|fr|conjuration|d}}, {{ç|fr|assassinat|e}} * İngilizce: {{ç|en|assassination}} * Macarca: {{ç|hu|merénylet}} * Türkçe: *: Osmanlı Türkçesi: {{ç|ota|صوءقصد}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Nişanyan}} ===Ek okumalar=== * {{proje bağlantısı|dil=tr|Vikipedi}} afc6rhd6dios4cey5jbokhb2z8j5czh 5672554 5672552 2026-06-29T20:04:56Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672554 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|otk}} {{b|ar|سوء قصد|}}. O da Arapça {{b|ar|سؤ||anlam=kötülük, fenalık, habaset}} ve Arapça {{b|ar|قصد ||anlam=kasıt, maksat}} sözcüklerinin birleşimidir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||su|i|kast}} ===Ad=== [[File:DC-1914-27-d-Sarajevo-cropped.jpg|küçükresim|Bir suikasti anlatan tablo. (2)]] {{tr-ad|istisna=incelme}} #{{t|dil=tr|cinayet}} Gizlice cana kıyma ve kötülük etmeye kalkışma. #* "Bir nefes alayım derken iğrenç bir suikasta uğradım." - Sait Faik Abasıyanık #{{t|dil=tr|cinayet|politika}} Bir devlet büyüğünü veya önemli bir kişiyi plan kurarak öldürme. ====Çekimleme==== {{tr-ad-tablo|istisna=incelme}} ====Deyimler==== * [[suikastta parmağı olmak]] ====Çeviriler==== {{Üst|suikast|tip=çeviriler}} * Almanca: {{ç|de|ْAttentat|n}} * Azerice: {{ç|az|sui-qəsd}} * Arapça: {{ç|ar|ْصُوءِقَصْد|m}} * Fransızca: {{ç|fr|complot|e}}, {{ç|fr|conjuration|d}}, {{ç|fr|assassinat|e}} * İngilizce: {{ç|en|assassination}} * Macarca: {{ç|hu|merénylet}} * Türkçe: *: Osmanlı Türkçesi: {{ç|ota|صوءقصد}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Nişanyan}} ===Ek okumalar=== * {{proje bağlantısı|dil=tr|Vikipedi}} h7idqvx8xwebmy4w6gr72vo4j1ehhnh meczup 0 127568 5672487 5254091 2026-06-29T14:22:30Z RamazanBayram94 67950 Düzeltme 5672487 wikitext text/x-wiki ==Türkçe== ===Köken=== {{k|dil=tr|ota}} {{z|ar|مجذوب}}, o da [[Arapça]] {{z|ar|مَجْذُوب}} kelimesinden gelmektedir. ===Söyleniş=== * {{IPA|dil=tr|/med͡ʒ.ˈzup/}} * {{h|dil=tr||mec|zup}} ===Ön ad=== {{tr-ön ad}} # [[akli|Aklî]] [[denge]]sini [[kaybetmek|kaybetmiş]] [[insan]]lara verilen genel ad #:{{örnek|dil=tr|"Bunlardan başka köyün iki '''meczubu''', bir cücesi vardır."|Yakup Kadri Karaosmanoğlu}} # {{t|dil=tr|İslâm|tarikat}} Genellikle [[din]]e olan bağlılığı yüzünden [[aklî denge]]sini [[kaybetmek|kaybetmiş]] olan [[insan]]lara yahut [[dergâh]] [[âyin]]lerinde kendilerinden geçen [[derviş]]. ===Kaynakça=== * {{kaynak-TDK}} kl2efaixefbgf4lfwae9045zjgnwps5 nouveau 0 130166 5672736 4417595 2026-06-30T08:48:41Z MustafaCavlak 59368 /* Fransızca */ 5672736 wikitext text/x-wiki ==Fransızca== ===Ön ad=== {{fr-ön ad|e2=nouvel|d=nouvelle|eç=nouveaux}} # [[yeni]] ishry3rlb30mcsimr9vs4iy1tqeo8if говорить 0 131590 5672591 3793194 2026-06-29T21:13:22Z MustafaCavlak 59368 /* Rusça */ 5672591 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|говори́ть|impf|pf=сказа́ть|pf2=поговори́ть}} # [[konuşmak]] (tamamlanmış: поговорить) # [[demek]], [[söylemek]] (tamamlanmış: сказать) evlzm2qp5c2gmflx3z47ivuyerca55h 5672592 5672591 2026-06-29T21:14:25Z MustafaCavlak 59368 5672592 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|говори́ть|impf|pf=сказа́ть|pf2=поговори́ть}} # [[konuşmak]] # [[demek]], [[söylemek]] qaqyctxmmgz52ka0nwxsgxrtsj1gos8 5672593 5672592 2026-06-29T21:15:19Z MustafaCavlak 59368 /* Rusça */ 5672593 wikitext text/x-wiki ==Rusça== ===Köken=== {{devralınan|ru|sla-pro|*govoriti}}. ===Eylem=== {{ru-eylem|говори́ть|impf|pf=сказа́ть|pf2=поговори́ть}} # [[konuşmak]] # [[demek]], [[söylemek]] rdea7m1dm7ju24n9zaqasnwa1v35lbg ნომერი 0 148204 5672733 4541372 2026-06-30T08:08:52Z MustafaCavlak 59368 /* Gürcüce */ 5672733 wikitext text/x-wiki ==Gürcüce== ===Söyleniş=== * {{IPA|dil=ka|[no̞me̞ɾi]}} ===Ad=== {{başlık başı|ka|ad}} # [[sayı]] shaicc0qiy43eqyzy9ktl0lkutma6zf bakalorya 0 169535 5672560 5656356 2026-06-29T20:36:35Z Satirdan kahraman 37401 TurkceMaddePanel 5672560 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|fr}} {{b|fr|baccalauréat|anlam=üniversite giriş sınavı}} sözcüğünden. Bu sözcük Geç Latince {{b|la|baccalarius|anlam=genç adam, şövalye adayı, bekâr}} sözcüğünden türetilmiştir. Geç Latince sözcük Eski Fransızca {{b|fro|bacheler|anlam=genç adam}} sözcüğünden alıntıdır. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||ba|ka|lo|rya}} ===Ad=== {{tr-ad}} # {{t|dil=tr|eğitim}} Üniversitelere girebilmek için lise öğreniminden sonra verilen olgunluk sınavı. #*{{kt|başlık=Acı Lokma|yazar=Fahri ERDİNÇ|yayıncı=Yordam Kitap |yıl=2006|sayfa=150|tanıklık='''Bakalorlayada''' edebiyattan takılıp diploma alamıyan bir arkadaşı da, yerli gazete «Bir ışık daha söndü» diye bir ağıt yayınladı...|dil=tr}} #*{{kt|dil=tr|başlık=Huzur|yazar=Ahmet Hamdi TANPINAR|yayıncı=Dergâh Yayınları|yıl=2022|baskı=39|sayfa=203|tanıklık= Mümtaz daha on sekiz yaşında '''bakaloryasını''' vermeğe hazırlanan lise talebesiyken, bu fikirlerin ocağına atılmıştı.}} ====Çekimleme==== {{tr-ad-tablo}} ====Çeviriler==== {{Üst|tip=çeviriler}} *Fince: {{ç|fi|ylioppilastutkinto}} *Fransızca: {{ç|fr|baccalauréat}} *İngilizce: {{ç|en|baccalauréat}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} l35mp2btuzr2jf95xl27udxsd45yx8t muhtarlık 0 169895 5672523 4386705 2026-06-29T19:08:06Z Satirdan kahraman 37401 TurkceMaddePanel 5672523 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{ek|dil=tr|muhtar|lık}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||muh|tar|lık}} ===Ad=== {{tr-ad}} [[File:Konakmersinli.jpg|küçükresim|Bir '''muhtarlık''' binası. (2)]] #{{t|dil=tr|kamu yönetimi}} Muhtarın görevi veya makamı. # Muhtarın görevini yaptığı yer. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} ogmcl8xqgvocc7fqal4hrwx6nk6011m yorgun 0 180935 5672531 5636846 2026-06-29T19:27:31Z Satirdan kahraman 37401 TurkceMaddePanel 5672531 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{ek|dil=tr|yorul|gun}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||yor|gun}} ===Ön ad=== {{tr-ön ad}} [[File:A tired worker.jpg|küçükresim|'''Yorgun''' adam, dinleniyor.]] #Çalışma vb. sebeplerle beden veya zihin etkinliği yavaşlayan, yorulmuş olan #*{{kt|başlık=Erbain|yazar=İsmet ÖZEL|yayıncı=TİYO|yıl=2016|sayfa=23|tanıklık='''Yorgun''' olamazdım çok uzaklardaydı yurdum çünkü|dil=tr}} ====Atasözleri==== * [[yorgun eşeğin çüş canına minnet]] ====Çeviriler==== {{Üst|tip=çeviriler}} *Almanca: {{ç|de|ermüdet}}, {{ç|de|müde}} *Azerice: {{ç|az|yorğun}} *Eski Türkçe: {{ç|otk|aruk}} *İngilizce: {{ç|en|tired}}, {{ç|en|weary}} *İsveççe: {{ç|sv|däven}}, {{ç|sv|trött}} *Norveççe: {{ç|no|trett}}, {{ç|no|trøtt}} *Tatarca: {{ç|tt|arığan}} *Türkmence: {{ç|tk|ýadaw}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} ==Gagavuzca== ===Köken=== {{köken|otk|dil=gag}} jor ===Ön ad=== {{başlık başı|gag|ön ad}} # [[yorgun#Türkçe|yorgun]] ===Kaynakça=== * {{kaynak-EtymDict}} ksab6bj89ufxsvf9lg2jshaoyuo0fy5 5672536 5672531 2026-06-29T19:31:53Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672536 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{ek|dil=tr|yorulmak|gun}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||yor|gun}} ===Ön ad=== {{tr-ön ad}} [[File:A tired worker.jpg|küçükresim|'''Yorgun''' adam, dinleniyor.]] #Çalışma vb. sebeplerle beden veya zihin etkinliği yavaşlayan, yorulmuş olan #*{{kt|başlık=Erbain|yazar=İsmet ÖZEL|yayıncı=TİYO|yıl=2016|sayfa=23|tanıklık='''Yorgun''' olamazdım çok uzaklardaydı yurdum çünkü|dil=tr}} ====Atasözleri==== * [[yorgun eşeğin çüş canına minnet]] ====Çeviriler==== {{Üst|tip=çeviriler}} *Almanca: {{ç|de|ermüdet}}, {{ç|de|müde}} *Azerice: {{ç|az|yorğun}} *Eski Türkçe: {{ç|otk|aruk}} *İngilizce: {{ç|en|tired}}, {{ç|en|weary}} *İsveççe: {{ç|sv|däven}}, {{ç|sv|trött}} *Norveççe: {{ç|no|trett}}, {{ç|no|trøtt}} *Tatarca: {{ç|tt|arığan}} *Türkmence: {{ç|tk|ýadaw}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} ==Gagavuzca== ===Köken=== {{köken|otk|dil=gag}} jor ===Ön ad=== {{başlık başı|gag|ön ad}} # [[yorgun#Türkçe|yorgun]] ===Kaynakça=== * {{kaynak-EtymDict}} 9dhdiatqllbpvxap2hh86pj56mkheay yük treni 0 182980 5672525 5264896 2026-06-29T19:14:25Z Satirdan kahraman 37401 TurkceMaddePanel 5672525 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|yük|tren}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||yük|tre|ni}} ===Ad=== {{tr-ad}} [[File:TCDD DE 33 075 Konak - Murat.jpg|küçükresim|Bir yük treni.]] #{{t|dil=tr|demiryolu taşıtları}} Yük taşımada kullanılan tren; [[yük katarı]], [[marşandiz]]. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} lyj55tzixl3bbpy5nvxsm37ycn0rupt yormak 0 191146 5672538 5265259 2026-06-29T19:33:21Z Satirdan kahraman 37401 TurkceMaddePanel 5672538 wikitext text/x-wiki ==Türkçe== ===Köken=== # {{k|dil=tr|tr}} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||yor|mak}} ===Eylem=== {{tr-eylem}} [[File:The Tired Dancer.jpg|küçükresim|Dans, kadını çok yormuş. (1) ]] [[File:Olaus Magnus - On the Art of Prophecy.jpg|küçükresim|Kâhin, ölü balıklara bir işaret yoruyor. (4)]] # [[yorgun]] duruma getirmek. #* "Teknik teferruatla okurlarımı yormak istemiyorum." - Falih Rıfkı Atay # sıkıntıya sokmak, üzmek #* "Ömer, kalbimi en çok yoran bir sima gibi hatırımda kaldı." - Halide Edip Adıvar # Bir anlam vermek, yorumlamak. #* "Hayvanlara insanca duygu ve düşünceler yormak ne derece doğrudur bunu da kestiremiyorum." - Haldun Taner #Bir sebebe bağlamak, bir duruma işaret saymak. ====Çekimleme==== {{tr-eylem-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *Azerice: {{ç|az|yozmaq}} *Eski Türkçe: {{ç|otk|argarmak}}, {{ç|otk|argurmak}} * Fransızca: {{ç|fr|fatiguer}}, {{ç|fr|épuiser}}, {{ç|fr|lasser}} * İngilizce: {{ç|en|tire}}, {{ç|en|exhaust}}, {{ç|en|wear out}} * İspanyolca: {{ç|es|cansar}}, {{ç|es|hartar}} *Karaçay Balkarca: {{ç|krc|arıt}} * Macarca: {{ç|hu|fáraszt}}, {{ç|hu|kimerít}} {{alt}} ===Kaynakça=== * {{KYK:TDK}} ==Çağatayca== ===Eylem=== {{başlık başı|chg|eylem}} # [[fal]] haber eylemek, güzel tâbir eylemek, nik söylemek ==Eski Türkçe== {{düzenle|alfabe=Eski Türkçe}} ===Eylem=== {{başlık başı|otk|eylem}} # tabir etmek # Yormak # [[yürümek]] ===Kaynakça=== * {{KÚNOS, Dr IGNAZ-ŞSEÇOS-1902}} mkhedrf37e835x6n5th9ytrs6hqggns yorulmak 0 191151 5672535 4183379 2026-06-29T19:31:05Z Satirdan kahraman 37401 TurkceMaddePanel 5672535 wikitext text/x-wiki ==Türkçe== ===Köken 1=== ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||yo|rul|mak}} ===Eylem=== {{tr-eylem}} [[File:Tired young nurse asleep and sitting at the table after long working day.jpg|küçükresim|Kız, '''yorulmuş.''']] # [[yorgun|Yorgun]] duruma gelmek. #* "El ele vererek dost olduk hemen / Yorulmaz dostuyla birlikte giden" - Enis Behiç Koryürek ===Köken 2=== ===Eylem=== {{tr-eylem}} # Bir sebebe bağlanılmak, yorumlanmak. #* Bu davranış iyiye yorulmaz. ====Çekimleme==== {{tr-eylem-tablo}} ====Çeviriler==== {{Üst|tip=çeviriler}} *Arapça: {{ç|ar|تعب}} *Fince: {{ç|fi|väsyä}}, {{ç|fi|uupua}} *İngilizce: {{ç|en|tire}} *İsveççe: {{ç|sv|bli trött}}, {{ç|sv|tröttna}} *Kürtçe: {{ç|ku|westîn}} *Rusça: {{ç|ru|уставать}} *Türkmence: {{ç|tk|aarmak}}, {{ç|tk|ýaadamak}}, {{ç|tk|ýorulmak}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} 5gvekfvoy8gakjivckrxmceqhj4f8w3 Zaman 0 199613 5672514 5246000 2026-06-29T18:10:53Z Satirdan kahraman 37401 TurkceMaddePanel 5672514 wikitext text/x-wiki {{bak|zaman}} ==Türkçe== ===Köken=== [[zaman]] sözcüğünden. ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||Za|man}} ===Özel ad=== {{tr-özel ad|k=1}} # {{özel ad|dil=tr|soyadı}} ====Çekimleme==== {{tr-ad-tablo}} 2rrzupe2j0f7ks91k16s6z98pmqagxn anaokulu 0 209957 5672518 5239165 2026-06-29T19:03:42Z Satirdan kahraman 37401 TurkceMaddePanel 5672518 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|ana|okul}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||a|na|o|ku|lu}} ===Ad=== {{tr-ad}} [[File:TR Izmir asv2020-02 img38 Löhner mansion.jpg|küçükresim|Anaokulu]] # {{t|eğitim|dil=tr}} öğrenim çağına henüz gelmemiş 2-6 yaş arasındaki çocukları okul düzenine hazırlayan eğitim kuruluşu; [[ana mektebi]] ====Çekimleme==== {{tr-ad-tablo}} ====Çeviriler==== {{Üst|tip=çeviriler}} *Almanca: {{ç|de|Vorschule}} *Felemenkçe: {{ç|nl|kleuterschool}} *Fince: {{ç|fi|esikoulu}} *İngilizce: {{ç|en|nursery school}}, {{ç|en|preschool}}, *İtalyanca: {{ç|it|asilo}}, {{ç|it|scuola materna}} *Kırım Tatarcası: {{ç|crh|}} *Kürtçe: {{ç|ku|zarrokxane}} *Tatarca: {{ç|tt|balalar baqçası}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} kn8hunh7hgce0ax96pd5pa5hu1mu4es 5672519 5672518 2026-06-29T19:04:03Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672519 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|ana|okul}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||a|na|o|ku|lu}} ===Ad=== {{tr-ad}} [[File:TR Izmir asv2020-02 img38 Löhner mansion.jpg|küçükresim|Anaokulu]] # {{t|eğitim|dil=tr}} öğrenim çağına henüz gelmemiş 2-6 yaş arasındaki çocukları okul düzenine hazırlayan eğitim kuruluşu; [[ana mektebi]] ====Çekimleme==== {{tr-ad-tablo|istisna=bileşik}} ====Çeviriler==== {{Üst|tip=çeviriler}} *Almanca: {{ç|de|Vorschule}} *Felemenkçe: {{ç|nl|kleuterschool}} *Fince: {{ç|fi|esikoulu}} *İngilizce: {{ç|en|nursery school}}, {{ç|en|preschool}}, *İtalyanca: {{ç|it|asilo}}, {{ç|it|scuola materna}} *Kırım Tatarcası: {{ç|crh|}} *Kürtçe: {{ç|ku|zarrokxane}} *Tatarca: {{ç|tt|balalar baqçası}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} k2xhm4gorl2fmdf88yr5323vux16x4z 5672520 5672519 2026-06-29T19:04:11Z Satirdan kahraman 37401 TurkceMaddePanel 5672520 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|ana|okul}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||a|na|o|ku|lu}} ===Ad=== {{tr-ad|istisna=bileşik}} [[File:TR Izmir asv2020-02 img38 Löhner mansion.jpg|küçükresim|Anaokulu]] # {{t|eğitim|dil=tr}} öğrenim çağına henüz gelmemiş 2-6 yaş arasındaki çocukları okul düzenine hazırlayan eğitim kuruluşu; [[ana mektebi]] ====Çekimleme==== {{tr-ad-tablo|istisna=bileşik}} ====Çeviriler==== {{Üst|tip=çeviriler}} *Almanca: {{ç|de|Vorschule}} *Felemenkçe: {{ç|nl|kleuterschool}} *Fince: {{ç|fi|esikoulu}} *İngilizce: {{ç|en|nursery school}}, {{ç|en|preschool}}, *İtalyanca: {{ç|it|asilo}}, {{ç|it|scuola materna}} *Kırım Tatarcası: {{ç|crh|}} *Kürtçe: {{ç|ku|zarrokxane}} *Tatarca: {{ç|tt|balalar baqçası}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} q7sw7hbmr69akut344bwwfvg8lba1k8 nişan yüzüğü 0 218248 5672631 4189570 2026-06-29T22:17:01Z Satirdan kahraman 37401 TurkceMaddePanel 5672631 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|nişan|yüzük}} ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||ni|şan|yü|zü|ğü}} ===Ad=== {{tr-ad}} [[File:Engagement rings.JPG|küçükresim|'''Nişan yüzüğü''' takan bir çift.]] #{{t|dil=tr|takılar|sembol adları|evlilik}} Evlenecek çiftin nişanlandıklarında taktıkları ve düğünden sonra da taşıdıkları halka biçimli yüzük; [[nişan halkası]] ====Çekimleme==== {{tr-ad-tablo}} ====Çeviriler==== {{Üst|tip=çeviriler}} *Danca: {{ç|da|forlovelsesring}} *Fince: {{ç|fi|kihlasormus}} *İngilizce: {{ç|en|engagement ring}} *İsveççe: {{ç|sv|förlovningsring}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} 41fzitifkjyr1o6hah7utq8pkcde68x virüs 0 220959 5672570 5344594 2026-06-29T20:48:03Z Satirdan kahraman 37401 TurkceMaddePanel 5672570 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|la}} {{b|la|vīrus|anlam=bir tür zararlı mikroorganizma}} sözcüğünden. Bu sözcük Latince {{b|la|virus|mana=zehir}} sözcüğünden alıntıdır. Latince sözcük Arkaik Latince tanıksız veya yeniden kurulmuş wisos biçiminden evrilmiştir. Bu biçim Hintavrupa Anadili tanıksız veya yeniden kurulmuş {{b|ine-pro|*wei̯s- |anlam=kötü kokmak, zehir}} biçiminden evrilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||vi|rüs}} ===Ad=== {{tr-ad}} [[File:Herpes simplex virus pap.jpg|thumb|Bir '''virüs'''. (1)]] [[File:SkyNet Virus Code.png|Bilgisayar '''virüsü'''. (2)]] # {{t|viroloji|dil=tr}} Hastalık yapıcı, bakterilerden daha küçük, yaşamak için bir başka hücrenin içine girmek zorunda olan ve ancak elektron mikroskobunda görülebilen parazit. #* "Benliğinin bir tarafına sokulup ölü yaşayan bir virüs Seher’in aşkı gibi müsait bir zemin bulunca canlanmış." - Refik Halit Karay # {{t|bilişim|dil=tr}} Değişik şekillerde bilgisayarlara yüklenen, programların bozulmasına, veri kaybına veya bilgisayarın olağan dışı çalışmasına neden olan program. ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== [[mutant virüs]] ====Üst kavramlar==== [[tıp]], [[malware]], [[patojen]], [[viroloji]], [[zararlı yazılım]] ====Türetilmiş kavramlar==== [[amogus]], [[sus]], ====Çeviriler==== {{Üst|tip=çeviriler}} *Afrikanca: {{ç|af|virus}} *Almanca: {{ç|de|Virus|n}}*Aragonca: {{ç|an|}} *Arapça: {{ç|ar|فِيرُوس|m}}, {{ç|ar|ڤِيرُوس‎|m}} *Arnavutça: {{ç|sq|virus}} *Bulgarca: {{ç|bg|вирус|m}} *Esperanto: {{ç|eo|viruso}} *Estonca: {{ç|et|viirus}} *Fransızca: {{ç|fr|virus|m}} *İngilizce: {{ç|en|virus}} *İsveççe: {{ç|sv|virus|n}} *Keçuva dili: {{ç|qu|miyu}} *Latince: {{ç|la|virus}} *Lehçe: {{ç|pl|wirus}} *Macarca: {{ç|hu|vírus}} *Norveççe: {{ç|no|virus}} *Rusça: {{ç|ru|вирус|m}}; {{ç|ru|вирус|m}} *Uygurca: {{ç|uz|ۋىرۇس}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} oqku8tl6sd8kecqupvfj97b355u4q6s 5672572 5672570 2026-06-29T20:48:13Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672572 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|la}} {{b|la|vīrus|anlam=bir tür zararlı mikroorganizma}} sözcüğünden. Bu sözcük Latince {{b|la|virus|mana=zehir}} sözcüğünden alıntıdır. Latince sözcük Arkaik Latince tanıksız veya yeniden kurulmuş wisos biçiminden evrilmiştir. Bu biçim Hintavrupa Anadili tanıksız veya yeniden kurulmuş {{b|ine-pro|*wei̯s- |anlam=kötü kokmak, zehir}} biçiminden evrilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||vi|rüs}} ===Ad=== {{tr-ad}} [[File:Herpes simplex virus pap.jpg|thumb|Bir '''virüs'''. (1)]] [[File:SkyNet Virus Code.png|küçükresim|Bilgisayar '''virüsü'''. (2)]] # {{t|viroloji|dil=tr}} Hastalık yapıcı, bakterilerden daha küçük, yaşamak için bir başka hücrenin içine girmek zorunda olan ve ancak elektron mikroskobunda görülebilen parazit. #* "Benliğinin bir tarafına sokulup ölü yaşayan bir virüs Seher’in aşkı gibi müsait bir zemin bulunca canlanmış." - Refik Halit Karay # {{t|bilişim|dil=tr}} Değişik şekillerde bilgisayarlara yüklenen, programların bozulmasına, veri kaybına veya bilgisayarın olağan dışı çalışmasına neden olan program. ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== [[mutant virüs]] ====Üst kavramlar==== [[tıp]], [[malware]], [[patojen]], [[viroloji]], [[zararlı yazılım]] ====Türetilmiş kavramlar==== [[amogus]], [[sus]], ====Çeviriler==== {{Üst|tip=çeviriler}} *Afrikanca: {{ç|af|virus}} *Almanca: {{ç|de|Virus|n}}*Aragonca: {{ç|an|}} *Arapça: {{ç|ar|فِيرُوس|m}}, {{ç|ar|ڤِيرُوس‎|m}} *Arnavutça: {{ç|sq|virus}} *Bulgarca: {{ç|bg|вирус|m}} *Esperanto: {{ç|eo|viruso}} *Estonca: {{ç|et|viirus}} *Fransızca: {{ç|fr|virus|m}} *İngilizce: {{ç|en|virus}} *İsveççe: {{ç|sv|virus|n}} *Keçuva dili: {{ç|qu|miyu}} *Latince: {{ç|la|virus}} *Lehçe: {{ç|pl|wirus}} *Macarca: {{ç|hu|vírus}} *Norveççe: {{ç|no|virus}} *Rusça: {{ç|ru|вирус|m}}; {{ç|ru|вирус|m}} *Uygurca: {{ç|uz|ۋىرۇس}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} 7e7siuz244ejrqmkkcn87i940ued859 5672574 5672572 2026-06-29T20:48:47Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672574 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|la}} {{b|la|vīrus|anlam=bir tür zararlı mikroorganizma}} sözcüğünden. Bu sözcük Latince {{b|la|virus|mana=zehir}} sözcüğünden alıntıdır. Latince sözcük Arkaik Latince tanıksız veya yeniden kurulmuş wisos biçiminden evrilmiştir. Bu biçim Hintavrupa Anadili tanıksız veya yeniden kurulmuş {{b|ine-pro|*wei̯s- |anlam=kötü kokmak, zehir}} biçiminden evrilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||vi|rüs}} ===Ad=== {{tr-ad}} [[File:Herpes simplex virus pap.jpg|thumb|Bir '''virüs'''. (1)]] [[File:SkyNet Virus Code.png|küçükresim|Bilgisayar '''virüsü'''. (2)]] # {{t|viroloji|dil=tr}} Hastalık yapıcı, bakterilerden daha küçük, yaşamak için bir başka hücrenin içine girmek zorunda olan ve ancak elektron mikroskobunda görülebilen parazit. #* "Benliğinin bir tarafına sokulup ölü yaşayan bir virüs Seher’in aşkı gibi müsait bir zemin bulunca canlanmış." - Refik Halit Karay # {{t|bilişim|dil=tr}} Değişik şekillerde bilgisayarlara yüklenen, programların bozulmasına, veri kaybına veya bilgisayarın olağan dışı çalışmasına neden olan program. ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== [[mutant virüs]] ====Üst kavramlar==== [[tıp]], [[malware]], [[patojen]], [[viroloji]], [[zararlı yazılım]] ====Çeviriler==== {{Üst|tip=çeviriler}} *Afrikanca: {{ç|af|virus}} *Almanca: {{ç|de|Virus|n}}*Aragonca: {{ç|an|}} *Arapça: {{ç|ar|فِيرُوس|m}}, {{ç|ar|ڤِيرُوس‎|m}} *Arnavutça: {{ç|sq|virus}} *Bulgarca: {{ç|bg|вирус|m}} *Esperanto: {{ç|eo|viruso}} *Estonca: {{ç|et|viirus}} *Fransızca: {{ç|fr|virus|m}} *İngilizce: {{ç|en|virus}} *İsveççe: {{ç|sv|virus|n}} *Keçuva dili: {{ç|qu|miyu}} *Latince: {{ç|la|virus}} *Lehçe: {{ç|pl|wirus}} *Macarca: {{ç|hu|vírus}} *Norveççe: {{ç|no|virus}} *Rusça: {{ç|ru|вирус|m}}; {{ç|ru|вирус|m}} *Uygurca: {{ç|uz|ۋىرۇس}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} mnpe7m9j4pn1lvjn2kol5e6htm48a2x 5672575 5672574 2026-06-29T20:48:50Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672575 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|la}} {{b|la|vīrus|anlam=bir tür zararlı mikroorganizma}} sözcüğünden. Bu sözcük Latince {{b|la|virus|mana=zehir}} sözcüğünden alıntıdır. Latince sözcük Arkaik Latince tanıksız veya yeniden kurulmuş wisos biçiminden evrilmiştir. Bu biçim Hintavrupa Anadili tanıksız veya yeniden kurulmuş {{b|ine-pro|*wei̯s- |anlam=kötü kokmak, zehir}} biçiminden evrilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||vi|rüs}} ===Ad=== {{tr-ad}} [[File:Herpes simplex virus pap.jpg|thumb|Bir '''virüs'''. (1)]] [[File:SkyNet Virus Code.png|küçükresim|Bilgisayar '''virüsü'''. (2)]] # {{t|viroloji|dil=tr}} Hastalık yapıcı, bakterilerden daha küçük, yaşamak için bir başka hücrenin içine girmek zorunda olan ve ancak elektron mikroskobunda görülebilen parazit. #* "Benliğinin bir tarafına sokulup ölü yaşayan bir virüs Seher’in aşkı gibi müsait bir zemin bulunca canlanmış." - Refik Halit Karay # {{t|bilişim|dil=tr}} Değişik şekillerde bilgisayarlara yüklenen, programların bozulmasına, veri kaybına veya bilgisayarın olağan dışı çalışmasına neden olan program. ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== [[mutant virüs]] ====Çeviriler==== {{Üst|tip=çeviriler}} *Afrikanca: {{ç|af|virus}} *Almanca: {{ç|de|Virus|n}}*Aragonca: {{ç|an|}} *Arapça: {{ç|ar|فِيرُوس|m}}, {{ç|ar|ڤِيرُوس‎|m}} *Arnavutça: {{ç|sq|virus}} *Bulgarca: {{ç|bg|вирус|m}} *Esperanto: {{ç|eo|viruso}} *Estonca: {{ç|et|viirus}} *Fransızca: {{ç|fr|virus|m}} *İngilizce: {{ç|en|virus}} *İsveççe: {{ç|sv|virus|n}} *Keçuva dili: {{ç|qu|miyu}} *Latince: {{ç|la|virus}} *Lehçe: {{ç|pl|wirus}} *Macarca: {{ç|hu|vírus}} *Norveççe: {{ç|no|virus}} *Rusça: {{ç|ru|вирус|m}}; {{ç|ru|вирус|m}} *Uygurca: {{ç|uz|ۋىرۇس}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} krffucxspc8z6p4fau8c24nzlkoza58 5672576 5672575 2026-06-29T20:49:09Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672576 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|la}} {{b|la|vīrus|anlam=bir tür zararlı mikroorganizma}} sözcüğünden. Bu sözcük Latince {{b|la|virus|mana=zehir}} sözcüğünden alıntıdır. Latince sözcük Arkaik Latince tanıksız veya yeniden kurulmuş wisos biçiminden evrilmiştir. Bu biçim Hintavrupa Anadili tanıksız veya yeniden kurulmuş {{b|ine-pro|*wei̯s- |anlam=kötü kokmak, zehir}} biçiminden evrilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||vi|rüs}} ===Ad=== {{tr-ad}} [[File:Herpes simplex virus pap.jpg|thumb|Bir '''virüs'''. (1)]] [[File:SkyNet Virus Code.png|küçükresim|Bilgisayar '''virüsü'''. (2)]] # {{t|viroloji|dil=tr}} Hastalık yapıcı, bakterilerden daha küçük, yaşamak için bir başka hücrenin içine girmek zorunda olan ve ancak elektron mikroskobunda görülebilen parazit. #* "Benliğinin bir tarafına sokulup ölü yaşayan bir virüs Seher’in aşkı gibi müsait bir zemin bulunca canlanmış." - Refik Halit Karay # {{t|bilişim|dil=tr}} Değişik şekillerde bilgisayarlara yüklenen, programların bozulmasına, veri kaybına veya bilgisayarın olağan dışı çalışmasına neden olan program. ====Çekimleme==== {{tr-ad-tablo}} ====Türetilmiş kavramlar==== [[koronavirüs]], [[mutant virüs]] ====Çeviriler==== {{Üst|tip=çeviriler}} *Afrikanca: {{ç|af|virus}} *Almanca: {{ç|de|Virus|n}}*Aragonca: {{ç|an|}} *Arapça: {{ç|ar|فِيرُوس|m}}, {{ç|ar|ڤِيرُوس‎|m}} *Arnavutça: {{ç|sq|virus}} *Bulgarca: {{ç|bg|вирус|m}} *Esperanto: {{ç|eo|viruso}} *Estonca: {{ç|et|viirus}} *Fransızca: {{ç|fr|virus|m}} *İngilizce: {{ç|en|virus}} *İsveççe: {{ç|sv|virus|n}} *Keçuva dili: {{ç|qu|miyu}} *Latince: {{ç|la|virus}} *Lehçe: {{ç|pl|wirus}} *Macarca: {{ç|hu|vírus}} *Norveççe: {{ç|no|virus}} *Rusça: {{ç|ru|вирус|m}}; {{ç|ru|вирус|m}} *Uygurca: {{ç|uz|ۋىرۇس}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Kubbealtı}} * {{KYK:Nişanyan}} 84qrzdvgdv56502z4c3j93xkptqdf6n sivrisinek 0 226514 5672559 5637800 2026-06-29T20:34:17Z Satirdan kahraman 37401 TurkceMaddePanel 5672559 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|sivri|sinek}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||siv|ri|si|nek}} ===Ad=== {{tr-ad}} [[Dosya:Aedes aegypti biting human.jpg|küçükresim|Bir '''sivrisinek.''']] # {{t|dil=tr|böcekler}} [[çift kanatlılar]]dan, insan ve memeli hayvanların kanıyla beslenen, birçok türü bulunan ve bir türü sıtma mikrobu aşılayan, sulak, bataklık yerlerde çok üreyen ve [[bulaşıcı]] hastalıkları yayan [[uçucu]] [[böcek]] #*{{mt|dergi=Öküz|sayı=15|yıl=1996|yazar=Orhan PAMUK|başlık=Gece Sivrisinek |sayfa=2|tanıklık=Kurtuldum sanmıştım, kafamı yastığa gömmüş, belki biraz da uyuklamıştım ki kendimi gecenin ortasında '''sivrisineğin''' uçuşu altında çaresiz ve yapayalnız buldum.|dil=tr}} ====Çekimleme==== {{tr-ad-tablo}} ====Atasözleri==== * [[anlayana sivrisinek saz, anlamayana davul zurna az]] ====Çeviriler==== {{üst|tip=çeviriler}} *Almanca: {{ç|de|Mücke|f}} *Baskça: {{ç|eu|eltxo}} *Bulgarca: {{ç|bg|комар|m}} *Çekçe: {{ç|cs|komár|m}} *Danca: {{ç|da|stikmyg}} *Endonezce: {{ç|id|nyamuk}} *Eski Türkçe: {{ç|otk|kümiçe}} *Estonca: {{ç|et|sääsk}} *Felemenkçe: {{ç|nl|mug}} *Fince: {{ç|fi|hyttynen}} *Fransızca: {{ç|fr|cousin|m}}, {{ç|fr|moustique|m}} *İngilizce: {{ç|en|gnat}}, {{ç|en|mosquito}} *İspanyolca: {{ç|es|mosquito}} *İsveççe: {{ç|sv|mygga}} *Kırım Tatarcası: {{ç|crh|çirkiy}}, {{ç|crh|şırqıy}} *Lao dili: {{ç|lo|ຍຸງ}} *Lehçe: {{ç|pl|komar|m}} *Macarca: {{ç|hu|szúnyog}} *Min Nan dili: {{ç|nan|báng}} *Norveççe: {{ç|no|mygg}} *Rumence: {{ç|ro|ţânţar}} *Rusça: {{ç|ru|комар|m}} *Tatarca: {{ç|tt|çerki}}, {{ç|tt|ozın-borın}} *Türkmence: {{ç|tk|çybyn}} *Vietnamca: {{ç|vi|muỗi}} {{alt}} ===Kaynakça=== * {{kaynak-TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} gdnircr4w5gwc0ed785x7n8p7udh1de çizgi 0 243278 5672716 5633096 2026-06-30T06:19:08Z Satirdan kahraman 37401 TurkceMaddePanel 5672716 wikitext text/x-wiki ==Türkçe== ===Söyleniş=== *{{tr-IPA}} * {{h|e|çiz|gi|dil=tr}} ===Ad=== [[File:Straight-line separator.png|thumb|'''Çizgi''' (1)]] [[File:Outline of a facial profile divided geometrically. Drawing, Wellcome V0009158.jpg|küçükresim|Bir erkeğin '''yüz çizgileri''' (2)]] {{tr-ad}} # çizilmek veya çeşitli yollarla oluşmuş iz; [[çizi]], [[hat]], [[tahril]] #*''Bu kâğıda üç '''çizgi''' çekti.'' - Ö. Seyfettin # yüz ve vücut hatlarının her biri #*{{kt|başlık=Siddharta|yazar=Hermann Hesse|yayıncı=Can Sanat Yayınları|yıl=2017|tercüme=Kâmuran Şipal|sayfa=93|tanıklık=Govinda yaşlanmıştı, ama yüzü eski '''çizgilerini''' koruyor, yüzünde bir şevk, sadakat, arayış ve ürkeklik ifadesi okunuyordu. |dil=tr}} # {{t|geometri|dil=tr}} bir noktanın noktasıyla oluşan biçim #*'''''Çizginin''' yalnız uzunluk boyutu vardır.'' # {{mecaz|dil=tr}} temel #*''Ben hayatımı yeniden ve bambaşka '''çizgiler''' üzerinde kuracağım.'' - A. İlhan # {{mecaz|dil=tr}} bir durumdan başka bir duruma atlanan, geçilen yer, sınır #*''Bu topluluklar arasında amatör ve profesyonel çizgisini de tam olarak çizebilmek kolay değildir.'' - Metin And ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== [[çizgi çekmek]], [[çizgi film]], [[çizgi hakemi]], [[çizgi im]], [[en çizgi]], [[kısa çizgi]] ====Türetilmiş kavramlar==== * [[çizgili]], [[çizgisiz]] ====Çeviriler==== {{Üst|tip=çeviriler}} *Almanca: {{ç|de|Linie|f}}, {{ç|de|Strich|m}} *Azerice: {{ç|az|çizgi}}, {{ç|az|xətt}} *Fince: {{ç|fi|viiva}}, {{ç|fi|juova}}, {{ç|fi|naarmu}}, {{ç|fi|piirto}} *İngilizce: {{ç|en|line}} *İspanyolca: {{ç|es|raya|f}} *İsveççe: {{ç|sv|linje}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} ==Azerice== ===Ad=== {{başlık başı|az|ad}} # {{b|tr|çizgi}} 1quejms5nxxdf6npfkmormcpjdf0a17 5672717 5672716 2026-06-30T06:21:08Z Satirdan kahraman 37401 TurkceMaddePanel 5672717 wikitext text/x-wiki ==Türkçe== ===Söyleniş=== *{{tr-IPA}} * {{h|e|çiz|gi|dil=tr}} ===Ad=== [[File:Straight-line separator.png|thumb|'''Çizgi''' (1)]] [[File:Outline of a facial profile divided geometrically. Drawing, Wellcome V0009158.jpg|küçükresim|Bir erkeğin '''yüz çizgileri''' (2)]] {{tr-ad}} # çizilmek veya çeşitli yollarla oluşmuş iz; [[çizi]], [[hat]], [[tahril]] #*''Bu kâğıda üç '''çizgi''' çekti.'' - Ö. Seyfettin # yüz ve vücut hatlarının her biri #*{{kt|başlık=Siddharta|yazar=Hermann Hesse|yayıncı=Can Sanat Yayınları|yıl=2017|tercüme=Kâmuran Şipal|sayfa=93|tanıklık=Govinda yaşlanmıştı, ama yüzü eski '''çizgilerini''' koruyor, yüzünde bir şevk, sadakat, arayış ve ürkeklik ifadesi okunuyordu. |dil=tr}} # {{t|geometri|dil=tr}} bir noktanın noktasıyla oluşan biçim #*'''''Çizginin''' yalnız uzunluk boyutu vardır.'' # {{mecaz|dil=tr}} temel #*''Ben hayatımı yeniden ve bambaşka '''çizgiler''' üzerinde kuracağım.'' - A. İlhan # {{mecaz|dil=tr}} bir durumdan başka bir duruma atlanan, geçilen yer, sınır #*''Bu topluluklar arasında amatör ve profesyonel çizgisini de tam olarak çizebilmek kolay değildir.'' - Metin And ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== [[çizgi çekmek]], [[çizgisinden sapmamak]] ====Türetilmiş kavramlar==== [[çizgi film]], [[çizgi hakemi]], [[çizgi im]], [[çizgi ölçek]], [[çizgi resim]], [[çizgi roman]], [[ana çizgi]], [[eğik çizgi]], [[gol çizgi teknolojisi]], [[kırık çizgi]], [[kırmızıçizgi]], [[kırmızı çizgi]], [[kısa çizgi]], [[uzun çizgi]], [[dış çizgiler durumu]], [[ev çizgileri]], [[atlama çizgisi]], [[aut çizgisi]], [[başlangıç çizgisi]], [[başucu çizgisi]], [[bitiş çizgisi]], [[çıkış çizgisi]], [[dip çizgisi]], [[doruk çizgisi]], [[ek çizgisi]], [[gol çizgisi]], [[ilave çizgisi]], [[kader çizgisi]], [[kale çizgisi]], [[kıyı çizgisi]], [[konuşma çizgisi]], [[korner çizgisi]], [[köşe çizgisi]], [[mafya çizgisi]], [[ölçek çizgisi]], [[ölçü çizgisi]], [[sahil çizgisi]], [[santra çizgisi]], [[serbest atış çizgisi]], [[su bölümü çizgisi]], [[taç çizgisi]], [[tarih değiştirme çizgisi]], [[ufuk çizgisi]], [[varış çizgisi]], [[yan çizgisi]] ====Çeviriler==== {{Üst|tip=çeviriler}} *Almanca: {{ç|de|Linie|f}}, {{ç|de|Strich|m}} *Azerice: {{ç|az|çizgi}}, {{ç|az|xətt}} *Fince: {{ç|fi|viiva}}, {{ç|fi|juova}}, {{ç|fi|naarmu}}, {{ç|fi|piirto}} *İngilizce: {{ç|en|line}} *İspanyolca: {{ç|es|raya|f}} *İsveççe: {{ç|sv|linje}} {{Alt}} ===Kaynakça=== * {{KYK:TDK}} ==Azerice== ===Ad=== {{başlık başı|az|ad}} # {{b|tr|çizgi}} qmz6xpssmrimnf2ignshykeftdocdu1 anofel 0 257371 5672557 5632229 2026-06-29T20:31:39Z Satirdan kahraman 37401 TurkceMaddePanel 5672557 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|fr}} {{b|fr|anophèle|anlam=sıtmaya neden olan sivrisinek türü}} sözcüğünden. Bu sözcük Eski Yunanca {{b|grc|ἀνωφελής|ç=anophelḗs|anlam=zayıflatan, kurutan}} sözcüğünden alıntıdır. Eski Yunanca sözcük Eski Yunanca {{b|grc|ὀφελής|ç=ophelḗs}} sözcüğünden {{b|grc|α-|ç=a(n)-|anlam=olumsuzluk ön eki}} ile türetilmiştir. Bu sözcük Eski Yunanca {{b|grc|ὀφέλλω|ç=ophéllō|anlam=güçlendirmek, kan ve can vermek, beslemek, yaramak}} fiilinden türetilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||a|no|fel}} ===Ad=== {{tr-ad}} [[Dosya:AnophelesGambiaemosquito.jpg|küçükresim|Anofel]] # {{t|dil=tr|böcekler}} [[sıtma sivrisineği]] #*{{kt|başlık= Dünkü - Bugünkü Akhisar|yazar=Ekmel İZDEM|yayıncı=Ülkü Basımevi|yıl=1944|sayfa=88|tanıklık=Rahmiye, Çamlatı, Kuvalık bataklıkları ile hiçbir disipline tâbi olmadan akan ve yer yer biriken sularda üreyen '''anufeller''' halkı sıtmadan kırıp geçiriyor.|dil=tr}} ===Çekimleme=== {{tr-ad-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *Fince: {{ç|fi|horkkahyttynen}}, {{ç|fi|malariahyttynen}} {{alt}} ===Kaynakça=== * {{kaynak-TDK}} ===Ek okumalar=== * {{proje bağlantısı|Vikipedi}} bk8n79goaiqs47uncihywkck87po3sg çıkış çizgisi 0 260001 5672720 5244424 2026-06-30T06:27:36Z Satirdan kahraman 37401 TurkceMaddePanel 5672720 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|çıkış|çizgi}} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||çı|kış|çiz|gi|si}} ===Ad=== {{tr-ad}} [[File:Starting line (Unsplash).jpg|küçükresim|Çıkış çizgisi ]] # {{t|dil=tr|spor}} Yarışın başlama yerini belirleyen beyaz çizgi; [[başlangıç çizgisi]]. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} aa0gyy6xhfy61bx5em20tc8q3teclto çizgi roman 0 260223 5672721 5244747 2026-06-30T06:30:45Z Satirdan kahraman 37401 TurkceMaddePanel 5672721 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|çizgi|roman}} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||çiz|gi|ro|man}} ===Ad=== {{tr-ad}} [[File:Copenhagen Comics 2015 - Comics of Taiwan.JPG|küçükresim|Çizgi romanlar]] #{{t|dil=tr|kitap}} Konuyu ve olaylar zincirini kesintisiz olarak resimleme yöntemiyle okuyucuya sunan roman. #* "… bilgisayarında düşman askerlerini öldürüyor, çizgi roman okuyordu." - Gülsüm Cengiz ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} rtqq5r1s5lqioa7sktp8dqv9mixh7hp dansöz 0 260532 5672556 5390947 2026-06-29T20:29:28Z Satirdan kahraman 37401 TurkceMaddePanel 5672556 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|fr}} {{b|fr|danseuse|anlam=kadın dansçı}} sözcüğünden. Bu sözcük Fransızca {{b|fr|danser|anlam=dans etmek}} fiilinden {{b|fr|+euse}} ekiyle türetilmiştir. Fransızca {{b|fr|danser}} fiili Germence tanıksız veya yeniden kurulmuş {{b|gem-pro|*dintjan|anlam=sallanmak, oynamak}} sözcüğünden alıntıdır. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||dan|söz}} ===Ad=== {{tr-ad}} [[File:Alla Kushnir, ukrainian belly dancer, 2015.png|küçükresim|Dansöz]] #{{t|dil=tr|meslekler|dans |kadın}} Dans etmeyi meslek edinmiş kadın. #* "Dansözü bu tip masalara yollayan cıvık insanlar da var çevrede." - Rauf Tamer ===Çekimleme=== {{tr-ad-tablo}} ====Çeviriler==== {{Üst|tip=çeviriler}} *Felemenkçe: {{ç|nl|danseres}}, {{ç|nl|beroepsdanseres}} *Fince: {{ç|fi|tanssijatar}}, {{ç|fi|vatsatanssija}} *Fransızca: {{ç|fr|danseuse}} *Kürtçe: {{ç|ku|çengî}}, {{ç|ku|sozan}], {{ç|ku|reqase}}, {{ç|ku|dansoz}} *Rusça: {{ç|ru|танцовщица}} {{Alt}} ====Kaynakça==== *{{kaynak-TDK}} 2dkcjky2sfub6t8gjuwapx00rhw6jwm gürül gürül 0 263692 5672524 4870454 2026-06-29T19:10:10Z Satirdan kahraman 37401 TurkceMaddePanel 5672524 wikitext text/x-wiki ==Türkçe== ===Köken=== ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||gü|rül|gü|rül}} ===Belirteç=== {{tr-belirteç}} [[File:حاله-الطقس-الان.webm|küçükresim|Yağmur '''gürül gürül''' yağıyor.]] # {{t|dil=tr|ses}} Bol ve gür çıkan veya akan şeylerin sesini anlatır ===Kaynakça=== * {{KYK:TDK}} m3fjzmc6g92glm56ug2qsckpq65ce66 halka olmak 0 263848 5672625 4410647 2026-06-29T22:09:48Z Satirdan kahraman 37401 TurkceMaddePanel 5672625 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|halka|olmak}} ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||hal|ka|ol|mak}} ===Eylem=== {{tr-eylem}} [[File:A group of naked people sit in a circle eating and drinking, Wellcome V0039363.jpg|küçükresim|İnsanlar '''halka olmuş,''' yemek yiyorlar.]] # Bir çember biçiminde dizilmek. #* {{tanıklık|dil=tr|yazar=Feyza HEPÇİLİNGİRLER|makale=Rio'da O Yaz Seninle|dergi=Öküz|sayı=41|yıl=1997|sayfa=20|metin=Tam orada yakılan ateşin çevresinde '''halka olmuş''' gençler yerel bir ezgiyi iyi hep bir ağızdan söyleyerek dönüyorlardı.}} ====Çekimleme==== {{tr-eylem-tablo}} ===Kaynakça=== * {{KYK:TDK}} c7kvmsznsp9nrdm9vvnxyrkt7bckn8t 5672626 5672625 2026-06-29T22:11:17Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672626 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|halka|olmak}} ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||hal|ka|ol|mak}} ===Eylem=== {{tr-eylem}} [[File:A Modern Village School- Education in Cambridgeshire, England, UK, 1944 D23630.jpg|küçükresim|Öğrenciler, '''halka olmuş,''' öğretmenlerini dinliyorlar.]] # Bir çember biçiminde dizilmek. #* {{tanıklık|dil=tr|yazar=Feyza HEPÇİLİNGİRLER|makale=Rio'da O Yaz Seninle|dergi=Öküz|sayı=41|yıl=1997|sayfa=20|metin=Tam orada yakılan ateşin çevresinde '''halka olmuş''' gençler yerel bir ezgiyi iyi hep bir ağızdan söyleyerek dönüyorlardı.}} ====Çekimleme==== {{tr-eylem-tablo}} ===Kaynakça=== * {{KYK:TDK}} p7hw8rb5m53ipj4daw2t6iex1vk73b6 halka yay 0 263849 5672639 4410657 2026-06-29T22:21:00Z Satirdan kahraman 37401 TurkceMaddePanel 5672639 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|halka|yay}} ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||hal|ka|yay}} ===Ad=== {{tr-ad}} #{{t|dil=tr|malzemeler}} [[anahtar|Boru anahtarının]] iyi tutmasını sağlayan ve çevreyle anahtar kolu arasına konulan sarmal yay. ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== ====Türetilmiş kavramlar==== ===Kaynakça=== * {{KYK:TDK}} qrw6n8ahlwuby0r7czu9bcmu9pmjxsq suç aleti 0 278008 5672550 4517395 2026-06-29T19:46:59Z Satirdan kahraman 37401 TurkceMaddePanel 5672550 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|suç|alet}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||suç|a|le|ti}} ===Ad=== {{tr-ad}} [[File:DC-1914-27-d-Sarajevo-cropped.jpg|küçükresim|Adam, '''suç aleti''' olarak siyah bir tabanca kullanıyor.]] #{{t|dil=tr|suç}} Suçun işlendiği alet veya suçun işlenmesinde söz konusu olan alet. #* "Katil suç aletini neden yatağının altında saklasın? Aptal mı bu adam?" - Pınar Kür ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} o2l1ppx57v9zj8g149vldx0iyuszaay yıl halkası 0 283820 5672627 4503236 2026-06-29T22:12:02Z Satirdan kahraman 37401 TurkceMaddePanel 5672627 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr| }} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||}} ===Ad=== {{tr-ad}} #{{t|dil=tr}} ====Çekimleme==== {{tr-ad-tablo}} ====Deyimler==== ====Türetilmiş kavramlar==== ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} stv7c5qv02yjsfki88fgotvsy7257er 5672628 5672627 2026-06-29T22:13:20Z Satirdan kahraman 37401 TurkceMaddePanel 5672628 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|yıl|halka}} ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||yıl|hal|ka|sı}} ===Ad=== {{tr-ad}} [[File:Roughly 200 years old - 54480567079.jpg|küçükresim|'''Yıl halkaları.''']] #{{t|dil=tr|bitki bilimi|ağaçlar|zamanın ölçülmesi}} Ağaçta, bir büyüme döneminde oluşan çembersel bölüm. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} ckw5ilsnafa7pqere7tj8tywxop75dm yorumlamak 0 284103 5672547 4869510 2026-06-29T19:43:25Z Satirdan kahraman 37401 TurkceMaddePanel 5672547 wikitext text/x-wiki ==Türkçe== ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||yo|rum|la|mak}} ===Eylem=== {{tr-eylem}} [[File:Olaus Magnus - On the Art of Prophecy.jpg|thumb|Kralın isteği üzerine ölü balıkları '''yorumlayan''' adamı gösteren bir çizim. (2)]] #{{t|dil=tr|edebiyat|yazı}} Bir yazıyı veya bir sözü yorum yaparak açıklamak;, [[tefsir etmek]] # Bir olaya, bir duruma bir anlam vermek; [[tabir etmek]] #*''Hasan Bey istediği gibi yorumlayabilir, bu beni ilgilendirmez.'' - H. E. Adıvar # {{t|dil=tr|müzik|tiyatro}} bir müzik parçasını veya bir tiyatro oyununu kendine özgü bir duyarlık ve teknikle çalmak, söylemek veya oynamak, [[icra etmek]] ====Çekimleme==== {{tr-eylem-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *Azerice: {{ç|az|şərh etmək}}, {{ç|az|kommentari vermək}}, {{ç|az|izah etmək}} * Fransızca: {{ç|fr|commenter}}, {{ç|fr|interpréter}} *Kürtçe: {{ç|ku|şîrove kirin}} {{alt}} ===Kaynakça=== * {{KYK:TDK}} 1zgilwi2tft22j6h6vh6495m899mziv театр 0 333294 5672561 4546986 2026-06-29T20:40:43Z MustafaCavlak 59368 /* Rusça */ 5672561 wikitext text/x-wiki ==Rusça== {{vikipedi|dil=ru}} ===Köken=== {{nakledilen|ru|fr|théâtre}}, {{kökenli|ru|la|theātrum}}, {{kökenli|ru|grc|θέατρον}}. ===Söyleniş=== * {{ses|dil=ru|Ru-театр.ogg}} ===Ad=== {{başlık başı|ru|ad|baş=теа́тр|c=e}} # [[tiyatro]] ====Çekimleme==== {{ru-ad-cansız-s-E-a|теа́тр}} ===Kaynakça=== * {{R:ru:Vasmer}} [[Kategori:Rusçada tiyatro]] [[Kategori:Rusçada binalar]] n7j61g7luf3my96c8w0ust03n4khfpb Güneş tacı 0 375350 5672582 3919105 2026-06-29T20:57:02Z Satirdan kahraman 37401 TurkceMaddePanel 5672582 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|Güneş|tacı}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||gü|neş|ta|cı}} ===Ad=== {{tr-ad}} [[Dosya:Solar_eclipse_1999_4.jpg|küçükresim|'''Güneş tacı,''' bir tutulma esnasında çıplak gözle görünmekte.]] #{{t|dil=tr|gök bilimi}} [[Güneş]] atmosferinin yoğunluğu çok düşük ve çok sıcak en dış katmanı, [[korona]] ====Çekimleme==== {{tr-ad-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *Fince: {{ç|fi|korona}} *İngilizce: {{ç|en|corona}} {{alt}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} gpsgv56tewna8ye7ylxmrcznvi00xe3 5672583 5672582 2026-06-29T20:57:24Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672583 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|Güneş|taç}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||gü|neş|ta|cı}} ===Ad=== {{tr-ad}} [[Dosya:Solar_eclipse_1999_4.jpg|küçükresim|'''Güneş tacı,''' bir tutulma esnasında çıplak gözle görünmekte.]] #{{t|dil=tr|gök bilimi}} [[Güneş]] atmosferinin yoğunluğu çok düşük ve çok sıcak en dış katmanı, [[korona]] ====Çekimleme==== {{tr-ad-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *Fince: {{ç|fi|korona}} *İngilizce: {{ç|en|corona}} {{alt}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} 02b8bcazoom2xp5eyem08zi0z4mz9yr katılaşmak 0 386356 5672712 4882946 2026-06-30T06:16:22Z Satirdan kahraman 37401 TurkceMaddePanel 5672712 wikitext text/x-wiki ==Türkçe== ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||ka|tı|laş|mak}} ===Eylem=== {{tr-eylem}} [[File:Pouring liquid mercury bionerd.jpg|küçükresim|Kaba dökülen sıvı, '''katılaşıyor''' (1)]] # {{terim|dil=tr|kimya|fizik}} [[katı|Katı]] duruma gelmek. #*''Çekilmişti sanki kara toprağın kanı / Yol soğumuş, '''katılaş'''mış bir ceset gibi” -E. B. Koryürek.'' # İz bırakmak, belirgin duruma gelmek. #*Bu tutumundan hoşlanmadığını belirten bir küçümsemenin çizgileri dondu, '''katılaş'''tı yüzünde.” -N. Cumalı.'' ====Çekimleme==== {{tr-eylem-tablo}} ====Kaynakça==== {{kaynak-TDK}} l5mzu8ybv9s2w095nh46tqto1g651n0 takım elbise 0 388252 5672711 5667302 2026-06-30T06:15:06Z Satirdan kahraman 37401 TurkceMaddePanel 5672711 wikitext text/x-wiki ==Türkçe== ===Köken=== {{birleşik|dil=tr|takım|elbise}} ===Söyleniş=== *{{tr-IPA}} *{{h|dil=tr||ta|kım|el|bi|se}} ===Ad=== {{tr-ad}} [[File:Mannequins in Galeries de la Capitale 3.jpg|küçükresim|Mankenlerin üstünde '''takım elbise''' var.]] # {{t|dil=tr|giyim}} Ceket ve pantolondan oluşan erkek giysisi, [[takım]] ===Çekimleme=== {{tr-ad-tablo}} ====Çeviriler==== {{üst|tip=çeviriler}} *Almanca: {{ç|de|Anzug|m}}, {{ç|de|Straßenanzug|m}} *Bulgarca: {{ç|bg|анцуг|m}} *Fince: {{ç|fi|pukuyhdistelmä}}, {{ç|fi|kokopuku}} *Fransızca: {{ç|fr|complet|m}} *İngilizce: {{ç|en|suit}} *İtalyanca: {{ç|it|abito completo|m}} {{alt}} ===Kaynakça=== *{{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} eyd713hq812tjlpbgj62fgfwgt5314s korona 0 388425 5672581 5215791 2026-06-29T20:55:05Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672581 wikitext text/x-wiki ==Türkçe== ===Köken=== {{k|la|dil=tr}} {{ç|la|corona}} ===Söyleniş=== * {{IPA|/coˈɾona/|dil=tr}} * {{h||ko|ro|na|dil=tr}} ===Ad=== {{tr-ad}} [[koronası|'''korona''' -sı]] # {{t|astronomi|dil=tr}} [[Güneş tacı]] # {{t|biyoloji|dil=tr}} aken tipi meyveye sahip bazı bitki meyvelerinin üzerinde taç şeklinde yer alan yapılar # {{t|biyoloji|dil=tr}} rotator gibi bazı hayvanların ön tarafında bulunan silli, halkasal yapı # {{t|kimya|yüksek gerilim|dil=tr}} yüksek gerilimli hatlarda ve kıvılcımla ateşlenen motorlarda daha çok gözlenen, oksijenin iyonlaşıp ozon oluşmasına sebep olan elektriksel boşalım etkisi. Oluşan ozonun şiddetli yükseltgeyici etkisinden dolayı bu tür yerlerdeki kablo, tel veya fiş bağlantılarında yükseltgenmeye dirençli naylon, neopren ve diğer sentetik maddeler kaplama için kullanılır. # {{t|halk dili|dil=tr}} [[korona virüsü]] veya [[koronavirüs]] ifadesinin halk arasındaki adı. ====Kelime birliktelikleri==== * {{mânâ|biyoloji, viroloji}} [[korona virüsü]] * {{mânâ|kimya, yüksek gerilim}} [[korona deşarjı]] ====Çeviriler==== {{üst|astronomi|tip=çeviriler}} * Almanca: {{ç|de|Sonnenkorona|f}} * Fince: {{ç|fi|korona}} * İngilizce: {{ç|en|corona}} * İsveççe: {{ç|sv|korona|c}} * İtalyanca: {{ç|it|corona|c}} {{alt}} ===Kaynakça=== * {{kaynak-TDK}} ===Ek okumalar=== * {{proje bağlantısı|Vikipedi}} ==Fince== ===Ad=== {{fi-ad}} # {{t|astronomi|dil=fi}} [[Güneş tacı]], {{b|tr|korona}} ==Macarca== ===Ad=== {{başlık başı|hu|ad}} # [[taç]], kraliyet tacı # [[Macaristan]]'ın 1892 ila 1926 arasında kullandığı [[para birimi]] 6ue8ayftq9ctl058dttjava0iik1miv 5672585 5672581 2026-06-29T21:01:30Z Satirdan kahraman 37401 TurkceMaddePanel 5672585 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|NL.}} {{b|la|corona(virus)|anlam=bir tür virüs}} sözcüğünden. Bu sözcük Latince {{b|la|corona|anlam=taç}} sözcüğünden türetilmiştir. ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||ko|ro|na}} ===Ad=== {{tr-ad}} [[Dosya:Solar_eclipse_1999_4.jpg|küçükresim|'''Korona,''' bir tutulma esnasında çıplak gözle görünmekte. (1)]] # {{t|gök bilimi|dil=tr}} [[Güneş tacı]] # {{t|biyoloji|dil=tr}} aken tipi meyveye sahip bazı bitki meyvelerinin üzerinde taç şeklinde yer alan yapılar # {{t|biyoloji|dil=tr}} rotator gibi bazı hayvanların ön tarafında bulunan silli, halkasal yapı # {{t|kimya|yüksek gerilim|dil=tr}} yüksek gerilimli hatlarda ve kıvılcımla ateşlenen motorlarda daha çok gözlenen, oksijenin iyonlaşıp ozon oluşmasına sebep olan elektriksel boşalım etkisi. Oluşan ozonun şiddetli yükseltgeyici etkisinden dolayı bu tür yerlerdeki kablo, tel veya fiş bağlantılarında yükseltgenmeye dirençli naylon, neopren ve diğer sentetik maddeler kaplama için kullanılır. # {{t|halk dili|dil=tr}} [[koronavirüs]]. ====Türetilmiş kavramlar==== [korona virüsü]], [[korona deşarjı]] ====Çeviriler==== {{üst|astronomi|tip=çeviriler}} * Almanca: {{ç|de|Sonnenkorona|f}} * Fince: {{ç|fi|korona}} * İngilizce: {{ç|en|corona}} * İsveççe: {{ç|sv|korona|c}} * İtalyanca: {{ç|it|corona|c}} {{alt}} ===Kaynakça=== * {{kaynak-TDK}} ===Ek okumalar=== * {{proje bağlantısı|Vikipedi}} ==Fince== ===Ad=== {{fi-ad}} # {{t|astronomi|dil=fi}} [[Güneş tacı]], {{b|tr|korona}} ==Macarca== ===Ad=== {{başlık başı|hu|ad}} # [[taç]], kraliyet tacı # [[Macaristan]]'ın 1892 ila 1926 arasında kullandığı [[para birimi]] 8o29rvz9moggo7h2r9t43x5sm7rcfys 5672587 5672585 2026-06-29T21:02:31Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672587 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|la}} {{b|la|corona|anlam=taç}} sözcüğünden . ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||ko|ro|na}} ===Ad=== {{tr-ad}} [[Dosya:Solar_eclipse_1999_4.jpg|küçükresim|'''Korona,''' bir tutulma esnasında çıplak gözle görünmekte. (1)]] # {{t|gök bilimi|dil=tr}} [[Güneş tacı]] # {{t|biyoloji|dil=tr}} aken tipi meyveye sahip bazı bitki meyvelerinin üzerinde taç şeklinde yer alan yapılar # {{t|biyoloji|dil=tr}} rotator gibi bazı hayvanların ön tarafında bulunan silli, halkasal yapı # {{t|kimya|yüksek gerilim|dil=tr}} yüksek gerilimli hatlarda ve kıvılcımla ateşlenen motorlarda daha çok gözlenen, oksijenin iyonlaşıp ozon oluşmasına sebep olan elektriksel boşalım etkisi. Oluşan ozonun şiddetli yükseltgeyici etkisinden dolayı bu tür yerlerdeki kablo, tel veya fiş bağlantılarında yükseltgenmeye dirençli naylon, neopren ve diğer sentetik maddeler kaplama için kullanılır. # {{t|halk dili|dil=tr}} [[koronavirüs]]. ====Türetilmiş kavramlar==== [korona virüsü]], [[korona deşarjı]] ====Çeviriler==== {{üst|astronomi|tip=çeviriler}} * Almanca: {{ç|de|Sonnenkorona|f}} * Fince: {{ç|fi|korona}} * İngilizce: {{ç|en|corona}} * İsveççe: {{ç|sv|korona|c}} * İtalyanca: {{ç|it|corona|c}} {{alt}} ===Kaynakça=== * {{kaynak-TDK}} ===Ek okumalar=== * {{proje bağlantısı|Vikipedi}} ==Fince== ===Ad=== {{fi-ad}} # {{t|astronomi|dil=fi}} [[Güneş tacı]], {{b|tr|korona}} ==Macarca== ===Ad=== {{başlık başı|hu|ad}} # [[taç]], kraliyet tacı # [[Macaristan]]'ın 1892 ila 1926 arasında kullandığı [[para birimi]] 5xpfnkm2dtu263bnz36fu8wb80e9lpd 5672588 5672587 2026-06-29T21:02:59Z Satirdan kahraman 37401 TurkceMaddePanel 5672588 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{köken|dil=tr|la}} {{b|la|corona|anlam=taç}} sözcüğünden . ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||ko|ro|na}} ===Ad=== {{tr-ad}} [[Dosya:Solar_eclipse_1999_4.jpg|küçükresim|'''Korona,''' bir tutulma esnasında çıplak gözle görünmekte. (1)]] # {{t|gök bilimi|dil=tr}} [[Güneş tacı]] # {{t|biyoloji|dil=tr}} aken tipi meyveye sahip bazı bitki meyvelerinin üzerinde taç şeklinde yer alan yapılar # {{t|biyoloji|dil=tr}} rotator gibi bazı hayvanların ön tarafında bulunan silli, halkasal yapı # {{t|kimya|yüksek gerilim|dil=tr}} yüksek gerilimli hatlarda ve kıvılcımla ateşlenen motorlarda daha çok gözlenen, oksijenin iyonlaşıp ozon oluşmasına sebep olan elektriksel boşalım etkisi. Oluşan ozonun şiddetli yükseltgeyici etkisinden dolayı bu tür yerlerdeki kablo, tel veya fiş bağlantılarında yükseltgenmeye dirençli naylon, neopren ve diğer sentetik maddeler kaplama için kullanılır. # {{t|halk dili|dil=tr}} [[koronavirüs]]. ====Çekimleme==== {{tr-ad-tablo}} ====Türetilmiş kavramlar==== [[korona virüsü]], [[korona deşarjı]] ====Çeviriler==== {{üst|astronomi|tip=çeviriler}} * Almanca: {{ç|de|Sonnenkorona|f}} * Fince: {{ç|fi|korona}} * İngilizce: {{ç|en|corona}} * İsveççe: {{ç|sv|korona|c}} * İtalyanca: {{ç|it|corona|c}} {{alt}} ===Kaynakça=== * {{kaynak-TDK}} ===Ek okumalar=== * {{proje bağlantısı|Vikipedi}} ==Fince== ===Ad=== {{fi-ad}} # {{t|astronomi|dil=fi}} [[Güneş tacı]], {{b|tr|korona}} ==Macarca== ===Ad=== {{başlık başı|hu|ad}} # [[taç]], kraliyet tacı # [[Macaristan]]'ın 1892 ila 1926 arasında kullandığı [[para birimi]] glinxvbe56yahof936jqutp4xgnsz8j Vikisözlük:Değişiklik sayılarına göre Vikisözlükçüler listesi 4 466356 5672590 5672368 2026-06-29T21:05:13Z YBot 37147 Güncelleme 5672590 wikitext text/x-wiki {{/begin}} <center> {| class="wikitable" ! # ! Kullanıcı ! Değişiklik sayısı ! Kullanıcı grupları |- | 1 | [[Kullanıcı:HastaLaVi2|HastaLaVi2]] | align="center" | 1.264.519 | arayüz yöneticisi, hizmetli |- | 2 | [[Kullanıcı:Victor Trevor|Victor Trevor]] | align="center" | 144.832 | |- | 3 | [[Kullanıcı:MustafaCavlak|MustafaCavlak]] | align="center" | 104.436 | hizmetli, geçici hesap IP görüntüleyici |- | 4 | [[Kullanıcı:Viki|Viki]] | align="center" | 45.152 | |- | 5 | [[Kullanıcı:By erdo can|By erdo can]] | align="center" | 42.866 | |- | 6 | [[Kullanıcı:Satirdan kahraman|Satirdan kahraman]] | align="center" | 37.863 | |- | 7 | [[Kullanıcı:Sae1962|Sae1962]] | align="center" | 34.149 | |- | 8 | [[Kullanıcı:Saltinbas|Saltinbas]] | align="center" | 26.434 | |- | 9 | [[Kullanıcı:MüjdeA|MüjdeA]] | align="center" | 25.502 | |- | 10 | [[Kullanıcı:Sabri76|Sabri76]] | align="center" | 20.349 | |- | 11 | [[Kullanıcı:Katakay|Katakay]] | align="center" | 19.415 | |- | 12 | [[Kullanıcı:Turgut46|Turgut46]] | align="center" | 17.534 | hizmetli |- | 13 | [[Kullanıcı:Vuzorg|Vuzorg]] | align="center" | 15.932 | |- | 14 | [[Kullanıcı:Ender|Ender]] | align="center" | 14.945 | |- | 15 | [[Kullanıcı:Kök|Kök]] | align="center" | 8.437 | |- | 16 | [[Kullanıcı:Curious|Curious]] | align="center" | 7.438 | |- | 17 | [[Kullanıcı:Bobcats|Bobcats]] | align="center" | 6.526 | |- | 18 | [[Kullanıcı:Nosferatü|Nosferatü]] | align="center" | 6.408 | |- | 19 | [[Kullanıcı:Uncitoyen|Uncitoyen]] | align="center" | 5.685 | hizmetli |- | 20 | [[Kullanıcı:Vikiyılmaz|Vikiyılmaz]] | align="center" | 5.369 | |- | 21 | [[Kullanıcı:Sinek~trwiktionary|Sinek~trwiktionary]] | align="center" | 5.221 | |- | 22 | [[Kullanıcı:YZCTEK|YZCTEK]] | align="center" | 4.880 | |- | 23 | [[Kullanıcı:Vorhon|Vorhon]] | align="center" | 4.699 | |- | 24 | [[Kullanıcı:LA2|LA2]] | align="center" | 4.433 | |- | 25 | [[Kullanıcı:Apisite|Apisite]] | align="center" | 4.428 | |- | 26 | [[Kullanıcı:B5.101.222.187|B5.101.222.187]] | align="center" | 4.259 | |- | 27 | [[Kullanıcı:Kavurt|Kavurt]] | align="center" | 4.088 | |- | 28 | [[Kullanıcı:Vitruvian|Vitruvian]] | align="center" | 4.054 | |- | 29 | [[Kullanıcı:123snake45|123snake45]] | align="center" | 3.971 | |- | 30 | [[Kullanıcı:Alikiroglu61|Alikiroglu61]] | align="center" | 3.773 | |- | 31 | [[Kullanıcı:3210|3210]] | align="center" | 3.716 | |- | 32 | [[Kullanıcı:Goreno|Goreno]] | align="center" | 3.474 | |- | 33 | [[Kullanıcı:Runningfridgesrule|Runningfridgesrule]] | align="center" | 3.119 | |- | 34 | [[Kullanıcı:Reality006|Reality006]] | align="center" | 3.099 | |- | 35 | [[Kullanıcı:HâlitM|HâlitM]] | align="center" | 3.052 | |- | 36 | [[Kullanıcı:Ahmed922229|Ahmed922229]] | align="center" | 3.009 | |- | 37 | [[Kullanıcı:Barishan|Barishan]] | align="center" | 2.971 | |- | 38 | [[Kullanıcı:Ekrem691|Ekrem691]] | align="center" | 2.398 | |- | 39 | [[Kullanıcı:Esege|Esege]] | align="center" | 2.321 | |- | 40 | [[Kullanıcı:Ugur Basak|Ugur Basak]] | align="center" | 2.267 | |- | 41 | [[Kullanıcı:Gamlıbaykuş|Gamlıbaykuş]] | align="center" | 2.098 | |- | 42 | [[Kullanıcı:AML ZİYA AKYASAN|AML ZİYA AKYASAN]] | align="center" | 1.989 | |- | 43 | [[Kullanıcı:Entry62|Entry62]] | align="center" | 1.959 | |- | 44 | [[Kullanıcı:Magurale|Magurale]] | align="center" | 1.854 | |- | 45 | [[Kullanıcı:Sihl fatma|Sihl fatma]] | align="center" | 1.835 | |- | 46 | [[Kullanıcı:Don Alessandro|Don Alessandro]] | align="center" | 1.815 | |- | 47 | [[Kullanıcı:Burudet88|Burudet88]] | align="center" | 1.791 | |- | 48 | [[Kullanıcı:Şêr|Şêr]] | align="center" | 1.668 | |- | 49 | [[Kullanıcı:Abuk78|Abuk78]] | align="center" | 1.534 | |- | 50 | [[Kullanıcı:Göktürker|Göktürker]] | align="center" | 1.508 | |- | 51 | [[Kullanıcı:Flanoz|Flanoz]] | align="center" | 1.463 | |- | 52 | [[Kullanıcı:Sa'y|Sa'y]] | align="center" | 1.345 | |- | 53 | [[Kullanıcı:Mzekiu|Mzekiu]] | align="center" | 1.344 | |- | 54 | [[Kullanıcı:Samleml enes bilgin|Samleml enes bilgin]] | align="center" | 1.315 | |- | 55 | [[Kullanıcı:İbrahim alican|İbrahim alican]] | align="center" | 1.292 | |- | 56 | [[Kullanıcı:SİHL Gökhan|SİHL Gökhan]] | align="center" | 1.278 | |- | 57 | [[Kullanıcı:Nazendegül|Nazendegül]] | align="center" | 1.260 | |- | 58 | [[Kullanıcı:ליאון12|ליאון12]] | align="center" | 1.178 | |- | 59 | [[Kullanıcı:Semlaml110|Semlaml110]] | align="center" | 1.174 | |- | 60 | [[Kullanıcı:Ahmetaslan|Ahmetaslan]] | align="center" | 1.141 | |- | 61 | [[Kullanıcı:Kibele|Kibele]] | align="center" | 1.136 | |- | 62 | [[Kullanıcı:Wwww8888|Wwww8888]] | align="center" | 1.125 | |- | 63 | [[Kullanıcı:Kmlblg 332|Kmlblg 332]] | align="center" | 1.124 | |- | 64 | [[Kullanıcı:Lagrium|Lagrium]] | align="center" | 1.094 | |- | 65 | [[Kullanıcı:SİHL ALİ MUSA|SİHL ALİ MUSA]] | align="center" | 1.045 | |- | 66 | [[Kullanıcı:Ömer faruk çakmak|Ömer faruk çakmak]] | align="center" | 996 | |- | 67 | [[Kullanıcı:Aybeg|Aybeg]] | align="center" | 968 | |- | 68 | [[Kullanıcı:ВМНС|ВМНС]] | align="center" | 962 | |- | 69 | [[Kullanıcı:Almanbet Janışev|Almanbet Janışev]] | align="center" | 954 | |- | 70 | [[Kullanıcı:Seksen iki yüz kırk beş|Seksen iki yüz kırk beş]] | align="center" | 931 | |- | 71 | [[Kullanıcı:Maxa|Maxa]] | align="center" | 912 | |- | 72 | [[Kullanıcı:Wiamboo|Wiamboo]] | align="center" | 880 | |- | 73 | [[Kullanıcı:SİHL Menzulekumaş|SİHL Menzulekumaş]] | align="center" | 846 | |- | 74 | [[Kullanıcı:Melkorettin|Melkorettin]] | align="center" | 812 | |- | 75 | [[Kullanıcı:Yasemin|Yasemin]] | align="center" | 802 | |- | 76 | [[Kullanıcı:Peirep|Peirep]] | align="center" | 791 | |- | 77 | [[Kullanıcı:Jeuwre|Jeuwre]] | align="center" | 786 | |- | 78 | [[Kullanıcı:S.ihl.selmaaksoy|S.ihl.selmaaksoy]] | align="center" | 781 | |- | 79 | [[Kullanıcı:Gibranist|Gibranist]] | align="center" | 773 | |- | 80 | [[Kullanıcı:Kmlblgfatmanur|Kmlblgfatmanur]] | align="center" | 771 | |- | 81 | [[Kullanıcı:Asım Hoca|Asım Hoca]] | align="center" | 765 | |- | 82 | [[Kullanıcı:Malafaya|Malafaya]] | align="center" | 765 | |- | 83 | [[Kullanıcı:Hagvoda|Hagvoda]] | align="center" | 760 | |- | 84 | [[Kullanıcı:YosefHan7|YosefHan7]] | align="center" | 756 | |- | 85 | [[Kullanıcı:Mustafahoca|Mustafahoca]] | align="center" | 745 | |- | 86 | [[Kullanıcı:ZazaLejyoner|ZazaLejyoner]] | align="center" | 740 | |- | 87 | [[Kullanıcı:Sürmene aml ve eml yusufcakir|Sürmene aml ve eml yusufcakir]] | align="center" | 721 | |- | 88 | [[Kullanıcı:Mehmet-k61|Mehmet-k61]] | align="center" | 670 | |- | 89 | [[Kullanıcı:Sinus46|Sinus46]] | align="center" | 670 | |- | 90 | [[Kullanıcı:Kml serhan|Kml serhan]] | align="center" | 668 | |- | 91 | [[Kullanıcı:TrDAsh|TrDAsh]] | align="center" | 639 | |- | 92 | [[Kullanıcı:Itidal|Itidal]] | align="center" | 635 | |- | 93 | [[Kullanıcı:Ömerbysl|Ömerbysl]] | align="center" | 635 | |- | 94 | [[Kullanıcı:Chelik99|Chelik99]] | align="center" | 587 | |- | 95 | [[Kullanıcı:Mereyü|Mereyü]] | align="center" | 556 | |- | 96 | [[Kullanıcı:Octahedron80|Octahedron80]] | align="center" | 547 | |- | 97 | [[Kullanıcı:ALİ İHSAN KARAMAN|ALİ İHSAN KARAMAN]] | align="center" | 533 | |- | 98 | [[Kullanıcı:Gullerdiyari|Gullerdiyari]] | align="center" | 520 | |- | 99 | [[Kullanıcı:Yeniler|Yeniler]] | align="center" | 515 | |- | 100 | [[Kullanıcı:Andac20|Andac20]] | align="center" | 509 | |- | 101 | [[Kullanıcı:Dilyâresi|Dilyâresi]] | align="center" | 485 | |- | 102 | [[Kullanıcı:Nerepla Keskin|Nerepla Keskin]] | align="center" | 483 | |- | 103 | [[Kullanıcı:Berkucar0|Berkucar0]] | align="center" | 473 | |- | 104 | [[Kullanıcı:İsmetaydin|İsmetaydin]] | align="center" | 465 | |- | 105 | [[Kullanıcı:Sadmleml enes|Sadmleml enes]] | align="center" | 464 | |- | 106 | [[Kullanıcı:Condmatstrel|Condmatstrel]] | align="center" | 461 | |- | 107 | [[Kullanıcı:Wutsje|Wutsje]] | align="center" | 440 | |- | 108 | [[Kullanıcı:Lo Ximiendo|Lo Ximiendo]] | align="center" | 435 | |- | 109 | [[Kullanıcı:Kml znnt|Kml znnt]] | align="center" | 430 | |- | 110 | [[Kullanıcı:CommonsDelinker|CommonsDelinker]] | align="center" | 423 | |- | 111 | [[Kullanıcı:Kendim|Kendim]] | align="center" | 418 | |- | 112 | [[Kullanıcı:Pathoschild|Pathoschild]] | align="center" | 413 | |- | 113 | [[Kullanıcı:Kemal.KURBAN|Kemal.KURBAN]] | align="center" | 413 | |- | 114 | [[Kullanıcı:Merbeg|Merbeg]] | align="center" | 410 | |- | 115 | [[Kullanıcı:Hamzahoca|Hamzahoca]] | align="center" | 405 | |- | 116 | [[Kullanıcı:AHMET AYSOY|AHMET AYSOY]] | align="center" | 393 | |- | 117 | [[Kullanıcı:Sihl ayhan|Sihl ayhan]] | align="center" | 385 | |- | 118 | [[Kullanıcı:A.d.m.l.ve.e.m.lmuhammet alican|A.d.m.l.ve.e.m.lmuhammet alican]] | align="center" | 383 | |- | 119 | [[Kullanıcı:Kvazimodo|Kvazimodo]] | align="center" | 381 | |- | 120 | [[Kullanıcı:Muhammet yardım|Muhammet yardım]] | align="center" | 378 | |- | 121 | [[Kullanıcı:Egemensen~trwiktionary|Egemensen~trwiktionary]] | align="center" | 376 | |- | 122 | [[Kullanıcı:Johnny281993|Johnny281993]] | align="center" | 376 | |- | 123 | [[Kullanıcı:Türkçe|Türkçe]] | align="center" | 368 | |- | 124 | [[Kullanıcı:Vito Genovese|Vito Genovese]] | align="center" | 365 | |- | 125 | [[Kullanıcı:Ata Kemal|Ata Kemal]] | align="center" | 365 | |- | 126 | [[Kullanıcı:ToprakM|ToprakM]] | align="center" | 365 | |- | 127 | [[Kullanıcı:Yunus Emre Biçer|Yunus Emre Biçer]] | align="center" | 364 | |- | 128 | [[Kullanıcı:Bm|Bm]] | align="center" | 347 | |- | 129 | [[Kullanıcı:Ampouble|Ampouble]] | align="center" | 343 | |- | 130 | [[Kullanıcı:SLÖzlem|SLÖzlem]] | align="center" | 343 | |- | 131 | [[Kullanıcı:S.orsev.ayşe kibaroğlu|S.orsev.ayşe kibaroğlu]] | align="center" | 341 | |- | 132 | [[Kullanıcı:MelekArı|MelekArı]] | align="center" | 336 | |- | 133 | [[Kullanıcı:Tegel|Tegel]] | align="center" | 313 | |- | 134 | [[Kullanıcı:The cat|The cat]] | align="center" | 311 | |- | 135 | [[Kullanıcı:SAL 378|SAL 378]] | align="center" | 305 | |- | 136 | [[Kullanıcı:Saml livess 61|Saml livess 61]] | align="center" | 297 | |- | 137 | [[Kullanıcı:Guljan|Guljan]] | align="center" | 296 | |- | 138 | [[Kullanıcı:Kmlblg272|Kmlblg272]] | align="center" | 292 | |- | 139 | [[Kullanıcı:SLDerya|SLDerya]] | align="center" | 292 | |- | 140 | [[Kullanıcı:Srhat|Srhat]] | align="center" | 285 | |- | 141 | [[Kullanıcı:2004onuralp|2004onuralp]] | align="center" | 285 | |- | 142 | [[Kullanıcı:Swam pl|Swam pl]] | align="center" | 284 | |- | 143 | [[Kullanıcı:Kml ibrahim|Kml ibrahim]] | align="center" | 275 | |- | 144 | [[Kullanıcı:MSchoentgen|MSchoentgen]] | align="center" | 274 | |- | 145 | [[Kullanıcı:Underfell Flowey|Underfell Flowey]] | align="center" | 270 | |- | 146 | [[Kullanıcı:Dbl2010|Dbl2010]] | align="center" | 264 | |- | 147 | [[Kullanıcı:Funda|Funda]] | align="center" | 260 | |- | 148 | [[Kullanıcı:Kebab in my butt|Kebab in my butt]] | align="center" | 260 | |- | 149 | [[Kullanıcı:Biyolojiyabikurdi|Biyolojiyabikurdi]] | align="center" | 258 | |- | 150 | [[Kullanıcı:Arhancelo|Arhancelo]] | align="center" | 256 | |- | 151 | [[Kullanıcı:SLnuray|SLnuray]] | align="center" | 251 | |- | 152 | [[Kullanıcı:Gilthuanas|Gilthuanas]] | align="center" | 250 | |- | 153 | [[Kullanıcı:Yorınçga573|Yorınçga573]] | align="center" | 249 | |- | 154 | [[Kullanıcı:SL.resul akyıldız|SL.resul akyıldız]] | align="center" | 247 | |- | 155 | [[Kullanıcı:SLözgül|SLözgül]] | align="center" | 246 | |- | 156 | [[Kullanıcı:Azxpetro|Azxpetro]] | align="center" | 244 | |- | 157 | [[Kullanıcı:Determinator|Determinator]] | align="center" | 243 | |- | 158 | [[Kullanıcı:Серк.123|Серк.123]] | align="center" | 243 | |- | 159 | [[Kullanıcı:Ceaeven|Ceaeven]] | align="center" | 240 | |- | 160 | [[Kullanıcı:Sihl gülten deveci|Sihl gülten deveci]] | align="center" | 237 | |- | 161 | [[Kullanıcı:Axbyc|Axbyc]] | align="center" | 236 | |- | 162 | [[Kullanıcı:Superyetkin|Superyetkin]] | align="center" | 235 | arayüz yöneticisi |- | 163 | [[Kullanıcı:Wikihez|Wikihez]] | align="center" | 228 | |- | 164 | [[Kullanıcı:SLFatma|SLFatma]] | align="center" | 227 | |- | 165 | [[Kullanıcı:Kmlblg240|Kmlblg240]] | align="center" | 224 | |- | 166 | [[Kullanıcı:Erdemaslancan|Erdemaslancan]] | align="center" | 224 | |- | 167 | [[Kullanıcı:Stml 172|Stml 172]] | align="center" | 220 | |- | 168 | [[Kullanıcı:SLUğurcan|SLUğurcan]] | align="center" | 219 | |- | 169 | [[Kullanıcı:Deknuydt|Deknuydt]] | align="center" | 217 | |- | 170 | [[Kullanıcı:Kwamikagami|Kwamikagami]] | align="center" | 212 | |- | 171 | [[Kullanıcı:Axis09|Axis09]] | align="center" | 210 | |- | 172 | [[Kullanıcı:OSMAN ÇAVUŞLU|OSMAN ÇAVUŞLU]] | align="center" | 209 | |- | 173 | [[Kullanıcı:Public class|Public class]] | align="center" | 208 | |- | 174 | [[Kullanıcı:Aivasedo|Aivasedo]] | align="center" | 205 | |- | 175 | [[Kullanıcı:Sal 390|Sal 390]] | align="center" | 203 | |- | 176 | [[Kullanıcı:Onuralpateş2004|Onuralpateş2004]] | align="center" | 202 | |- | 177 | [[Kullanıcı:Aslan yakup|Aslan yakup]] | align="center" | 197 | |- | 178 | [[Kullanıcı:SLebru|SLebru]] | align="center" | 197 | |- | 179 | [[Kullanıcı:Sal-zeynep|Sal-zeynep]] | align="center" | 196 | |- | 180 | [[Kullanıcı:SLRahman|SLRahman]] | align="center" | 194 | |- | 181 | [[Kullanıcı:Chapultepec|Chapultepec]] | align="center" | 193 | |- | 182 | [[Kullanıcı:Trong Dang|Trong Dang]] | align="center" | 192 | |- | 183 | [[Kullanıcı:Syum90|Syum90]] | align="center" | 185 | |- | 184 | [[Kullanıcı:NURULLAH GÜLDAL|NURULLAH GÜLDAL]] | align="center" | 183 | |- | 185 | [[Kullanıcı:Vikiçizer|Vikiçizer]] | align="center" | 182 | |- | 186 | [[Kullanıcı:MehmedKM|MehmedKM]] | align="center" | 182 | |- | 187 | [[Kullanıcı:Bikarhêner|Bikarhêner]] | align="center" | 180 | |- | 188 | [[Kullanıcı:Şaşılık|Şaşılık]] | align="center" | 179 | |- | 189 | [[Kullanıcı:Felecita|Felecita]] | align="center" | 176 | |- | 190 | [[Kullanıcı:Ddenkel~trwiktionary|Ddenkel~trwiktionary]] | align="center" | 175 | |- | 191 | [[Kullanıcı:Sezinumaykucuk|Sezinumaykucuk]] | align="center" | 175 | |- | 192 | [[Kullanıcı:Sallapattias|Sallapattias]] | align="center" | 171 | |- | 193 | [[Kullanıcı:SLburhantuncer|SLburhantuncer]] | align="center" | 168 | |- | 194 | [[Kullanıcı:Bahattin|Bahattin]] | align="center" | 168 | |- | 195 | [[Kullanıcı:Kml suleakguc|Kml suleakguc]] | align="center" | 167 | |- | 196 | [[Kullanıcı:Sihl ASİYE|Sihl ASİYE]] | align="center" | 167 | |- | 197 | [[Kullanıcı:Mehmetkasımay|Mehmetkasımay]] | align="center" | 165 | |- | 198 | [[Kullanıcı:SLfatma254|SLfatma254]] | align="center" | 163 | |- | 199 | [[Kullanıcı:Yko 235|Yko 235]] | align="center" | 162 | |- | 200 | [[Kullanıcı:Stml 158|Stml 158]] | align="center" | 159 | |- | 201 | [[Kullanıcı:Stml 121|Stml 121]] | align="center" | 156 | |- | 202 | [[Kullanıcı:SLEngin|SLEngin]] | align="center" | 154 | |- | 203 | [[Kullanıcı:Serdar62|Serdar62]] | align="center" | 154 | |- | 204 | [[Kullanıcı:Terryclient|Terryclient]] | align="center" | 151 | |- | 205 | [[Kullanıcı:Czeski Wratek|Czeski Wratek]] | align="center" | 151 | |- | 206 | [[Kullanıcı:Calq|Calq]] | align="center" | 148 | |- | 207 | [[Kullanıcı:Sihl Ramazan Erdöl|Sihl Ramazan Erdöl]] | align="center" | 146 | |- | 208 | [[Kullanıcı:Drabdullayev17|Drabdullayev17]] | align="center" | 140 | |- | 209 | [[Kullanıcı:Lionel Cristiano|Lionel Cristiano]] | align="center" | 139 | |- | 210 | [[Kullanıcı:Hasan Sami|Hasan Sami]] | align="center" | 138 | |- | 211 | [[Kullanıcı:Abuk SABUK|Abuk SABUK]] | align="center" | 138 | |- | 212 | [[Kullanıcı:Dilci|Dilci]] | align="center" | 137 | |- | 213 | [[Kullanıcı:Matiia|Matiia]] | align="center" | 137 | |- | 214 | [[Kullanıcı:SİHL İSA ELER|SİHL İSA ELER]] | align="center" | 135 | |- | 215 | [[Kullanıcı:Ata Kemal Ayaser|Ata Kemal Ayaser]] | align="center" | 135 | |- | 216 | [[Kullanıcı:Emperyan|Emperyan]] | align="center" | 135 | |- | 217 | [[Kullanıcı:Lou|Lou]] | align="center" | 133 | |- | 218 | [[Kullanıcı:Rolby|Rolby]] | align="center" | 133 | |- | 219 | [[Kullanıcı:Peter Berbe|Peter Berbe]] | align="center" | 133 | |- | 220 | [[Kullanıcı:Eminovič|Eminovič]] | align="center" | 132 | |- | 221 | [[Kullanıcı:Hdayetozsoy|Hdayetozsoy]] | align="center" | 131 | |- | 222 | [[Kullanıcı:Fankibiber|Fankibiber]] | align="center" | 129 | |- | 223 | [[Kullanıcı:GerardM|GerardM]] | align="center" | 125 | |- | 224 | [[Kullanıcı:Ka dir 641|Ka dir 641]] | align="center" | 125 | |- | 225 | [[Kullanıcı:Mesutbolukbas|Mesutbolukbas]] | align="center" | 124 | |- | 226 | [[Kullanıcı:SLemine607 10D|SLemine607 10D]] | align="center" | 122 | |- | 227 | [[Kullanıcı:Tarihçi Selo|Tarihçi Selo]] | align="center" | 120 | |- | 228 | [[Kullanıcı:Lambiam|Lambiam]] | align="center" | 120 | |- | 229 | [[Kullanıcı:Dodecaplex|Dodecaplex]] | align="center" | 120 | |- | 230 | [[Kullanıcı:Vay~trwiktionary|Vay~trwiktionary]] | align="center" | 119 | |- | 231 | [[Kullanıcı:Yavuz Atasever|Yavuz Atasever]] | align="center" | 118 | |- | 232 | [[Kullanıcı:Metal Militia|Metal Militia]] | align="center" | 117 | |- | 233 | [[Kullanıcı:Aarp65|Aarp65]] | align="center" | 117 | |- | 234 | [[Kullanıcı:Eyüp Türküm|Eyüp Türküm]] | align="center" | 117 | |- | 235 | [[Kullanıcı:Kalem.metin|Kalem.metin]] | align="center" | 117 | |- | 236 | [[Kullanıcı:Mario The PS2 Guy|Mario The PS2 Guy]] | align="center" | 117 | |- | 237 | [[Kullanıcı:Meyegon|Meyegon]] | align="center" | 115 | |- | 238 | [[Kullanıcı:Cûndûllah el-Kurdî|Cûndûllah el-Kurdî]] | align="center" | 115 | |- | 239 | [[Kullanıcı:Minorax|Minorax]] | align="center" | 115 | |- | 240 | [[Kullanıcı:Baris6161TURK|Baris6161TURK]] | align="center" | 113 | |- | 241 | [[Kullanıcı:Kml 207aysegül|Kml 207aysegül]] | align="center" | 112 | |- | 242 | [[Kullanıcı:SLseda|SLseda]] | align="center" | 111 | |- | 243 | [[Kullanıcı:Kmoksy|Kmoksy]] | align="center" | 111 | |- | 244 | [[Kullanıcı:LesChloroformistes|LesChloroformistes]] | align="center" | 110 | |- | 245 | [[Kullanıcı:Ladsgroup|Ladsgroup]] | align="center" | 109 | |- | 246 | [[Kullanıcı:Müntesib|Müntesib]] | align="center" | 109 | |- | 247 | [[Kullanıcı:Kmlrbabalik|Kmlrbabalik]] | align="center" | 108 | |- | 248 | [[Kullanıcı:Kmlblg86|Kmlblg86]] | align="center" | 108 | |- | 249 | [[Kullanıcı:S htk 117|S htk 117]] | align="center" | 105 | |- | 250 | [[Kullanıcı:SLGamze|SLGamze]] | align="center" | 105 | |- | 251 | [[Kullanıcı:Doğru Tercüman|Doğru Tercüman]] | align="center" | 105 | |- | 252 | [[Kullanıcı:Küçükdere iöo gülay|Küçükdere iöo gülay]] | align="center" | 104 | |- | 253 | [[Kullanıcı:Gülşah|Gülşah]] | align="center" | 102 | |- | 254 | [[Kullanıcı:Balamax|Balamax]] | align="center" | 102 | |- | 255 | [[Kullanıcı:Ormanbotanigi|Ormanbotanigi]] | align="center" | 101 | |- | 256 | [[Kullanıcı:Stml 176|Stml 176]] | align="center" | 101 | |- | 257 | [[Kullanıcı:Stml 165|Stml 165]] | align="center" | 101 | |- | 258 | [[Kullanıcı:Kmlblg399|Kmlblg399]] | align="center" | 100 | |- | 259 | [[Kullanıcı:Nerval|Nerval]] | align="center" | 99 | |- | 260 | [[Kullanıcı:Stml 72|Stml 72]] | align="center" | 98 | |- | 261 | [[Kullanıcı:Stryn|Stryn]] | align="center" | 97 | |- | 262 | [[Kullanıcı:Küçükdere iöo sinan|Küçükdere iöo sinan]] | align="center" | 96 | |- | 263 | [[Kullanıcı:Dünya vatandaşı|Dünya vatandaşı]] | align="center" | 95 | |- | 264 | [[Kullanıcı:Muhammet yazıcı|Muhammet yazıcı]] | align="center" | 95 | |- | 265 | [[Kullanıcı:SİHL 729|SİHL 729]] | align="center" | 95 | |- | 266 | [[Kullanıcı:Xorasan|Xorasan]] | align="center" | 95 | |- | 267 | [[Kullanıcı:Fiilçeker|Fiilçeker]] | align="center" | 94 | |- | 268 | [[Kullanıcı:RadiX|RadiX]] | align="center" | 94 | |- | 269 | [[Kullanıcı:Muallim Fatih|Muallim Fatih]] | align="center" | 94 | |- | 270 | [[Kullanıcı:Marrovi|Marrovi]] | align="center" | 94 | |- | 271 | [[Kullanıcı:Spacebirdy|Spacebirdy]] | align="center" | 93 | |- | 272 | [[Kullanıcı:MhmtÖ|MhmtÖ]] | align="center" | 93 | |- | 273 | [[Kullanıcı:Berr.in|Berr.in]] | align="center" | 92 | |- | 274 | [[Kullanıcı:SL-busenur.523|SL-busenur.523]] | align="center" | 91 | |- | 275 | [[Kullanıcı:SLİpek|SLİpek]] | align="center" | 90 | |- | 276 | [[Kullanıcı:Kmlblgözlem|Kmlblgözlem]] | align="center" | 89 | |- | 277 | [[Kullanıcı:Cavlak-FS|Cavlak-FS]] | align="center" | 88 | |- | 278 | [[Kullanıcı:Azminwan|Azminwan]] | align="center" | 87 | |- | 279 | [[Kullanıcı:Moonpulsar|Moonpulsar]] | align="center" | 87 | |- | 280 | [[Kullanıcı:Stml 171|Stml 171]] | align="center" | 86 | |- | 281 | [[Kullanıcı:Turkmen|Turkmen]] | align="center" | 85 | |- | 282 | [[Kullanıcı:Xyz...|Xyz...]] | align="center" | 84 | |- | 283 | [[Kullanıcı:Stml 117|Stml 117]] | align="center" | 83 | |- | 284 | [[Kullanıcı:Juliancolton|Juliancolton]] | align="center" | 81 | |- | 285 | [[Kullanıcı:Ludwig20|Ludwig20]] | align="center" | 81 | |- | 286 | [[Kullanıcı:2004ateş|2004ateş]] | align="center" | 81 | |- | 287 | [[Kullanıcı:Süleymanbedir|Süleymanbedir]] | align="center" | 80 | |- | 288 | [[Kullanıcı:Kıdemli|Kıdemli]] | align="center" | 80 | |- | 289 | [[Kullanıcı:Karabat Kuşu|Karabat Kuşu]] | align="center" | 79 | |- | 290 | [[Kullanıcı:SAML VE EML CEMİL BAYRAM|SAML VE EML CEMİL BAYRAM]] | align="center" | 79 | |- | 291 | [[Kullanıcı:Semlaml111|Semlaml111]] | align="center" | 79 | |- | 292 | [[Kullanıcı:SEML Turan ÇAKIR|SEML Turan ÇAKIR]] | align="center" | 78 | |- | 293 | [[Kullanıcı:Küçükdere iöo celilakyürek|Küçükdere iöo celilakyürek]] | align="center" | 78 | |- | 294 | [[Kullanıcı:SLemine613|SLemine613]] | align="center" | 78 | |- | 295 | [[Kullanıcı:Dokuz sekiz|Dokuz sekiz]] | align="center" | 78 | |- | 296 | [[Kullanıcı:Sayonzei|Sayonzei]] | align="center" | 78 | |- | 297 | [[Kullanıcı:İlhanbiskin|İlhanbiskin]] | align="center" | 77 | |- | 298 | [[Kullanıcı:İsmailhoca|İsmailhoca]] | align="center" | 77 | |- | 299 | [[Kullanıcı:Kmlblg80|Kmlblg80]] | align="center" | 77 | |- | 300 | [[Kullanıcı:Masseman|Masseman]] | align="center" | 76 | |- | 301 | [[Kullanıcı:Ridvanu|Ridvanu]] | align="center" | 75 | |- | 302 | [[Kullanıcı:Ege yalcin~trwiktionary|Ege yalcin~trwiktionary]] | align="center" | 75 | |- | 303 | [[Kullanıcı:İbrhm.kuru|İbrhm.kuru]] | align="center" | 73 | |- | 304 | [[Kullanıcı:Mustafa Eşitgen|Mustafa Eşitgen]] | align="center" | 73 | |- | 305 | [[Kullanıcı:Fagus|Fagus]] | align="center" | 73 | |- | 306 | [[Kullanıcı:SL Pelin|SL Pelin]] | align="center" | 72 | |- | 307 | [[Kullanıcı:Seninbey~trwiktionary|Seninbey~trwiktionary]] | align="center" | 72 | |- | 308 | [[Kullanıcı:EmrahÖ|EmrahÖ]] | align="center" | 72 | |- | 309 | [[Kullanıcı:BitikciKebbenek|BitikciKebbenek]] | align="center" | 72 | |- | 310 | [[Kullanıcı:Emree4|Emree4]] | align="center" | 71 | |- | 311 | [[Kullanıcı:Kontrolcu|Kontrolcu]] | align="center" | 71 | |- | 312 | [[Kullanıcı:Nebra|Nebra]] | align="center" | 71 | |- | 313 | [[Kullanıcı:Pembe karadeniz|Pembe karadeniz]] | align="center" | 71 | |- | 314 | [[Kullanıcı:Stml 147|Stml 147]] | align="center" | 70 | |- | 315 | [[Kullanıcı:SEMLNazımKURŞUN|SEMLNazımKURŞUN]] | align="center" | 70 | |- | 316 | [[Kullanıcı:Giresunlu1993|Giresunlu1993]] | align="center" | 70 | |- | 317 | [[Kullanıcı:Plenumchamber~trwiktionary|Plenumchamber~trwiktionary]] | align="center" | 69 | |- | 318 | [[Kullanıcı:~2026-19042-98|~2026-19042-98]] | align="center" | 69 | |- | 319 | [[Kullanıcı:Rock on She|Rock on She]] | align="center" | 67 | |- | 320 | [[Kullanıcı:SLSerkan|SLSerkan]] | align="center" | 65 | |- | 321 | [[Kullanıcı:Karduelis|Karduelis]] | align="center" | 65 | |- | 322 | [[Kullanıcı:Zontollektuel|Zontollektuel]] | align="center" | 65 | |- | 323 | [[Kullanıcı:Evrenkoruyan|Evrenkoruyan]] | align="center" | 64 | |- | 324 | [[Kullanıcı:Adanalınacak|Adanalınacak]] | align="center" | 64 | |- | 325 | [[Kullanıcı:Hapşu|Hapşu]] | align="center" | 63 | |- | 326 | [[Kullanıcı:Dixtosa|Dixtosa]] | align="center" | 63 | |- | 327 | [[Kullanıcı:El.wikt.user|El.wikt.user]] | align="center" | 62 | |- | 328 | [[Kullanıcı:SL özge üstün|SL özge üstün]] | align="center" | 62 | |- | 329 | [[Kullanıcı:Sal hasanilhan|Sal hasanilhan]] | align="center" | 61 | |- | 330 | [[Kullanıcı:Prenses|Prenses]] | align="center" | 60 | |- | 331 | [[Kullanıcı:Tofeiku|Tofeiku]] | align="center" | 60 | |- | 332 | [[Kullanıcı:Sihl Murat|Sihl Murat]] | align="center" | 59 | |- | 333 | [[Kullanıcı:Renamed user 1e23409a06e0b7922c2dfc98dde51974|Renamed user 1e23409a06e0b7922c2dfc98dde51974]] | align="center" | 59 | |- | 334 | [[Kullanıcı:Arnavutsezgin|Arnavutsezgin]] | align="center" | 58 | |- | 335 | [[Kullanıcı:Erkan Yilmaz|Erkan Yilmaz]] | align="center" | 58 | |- | 336 | [[Kullanıcı:Galibibülent|Galibibülent]] | align="center" | 57 | |- | 337 | [[Kullanıcı:S.orsev.dilek soydan|S.orsev.dilek soydan]] | align="center" | 57 | |- | 338 | [[Kullanıcı:Stml 183|Stml 183]] | align="center" | 57 | |- | 339 | [[Kullanıcı:Buzulkuşu|Buzulkuşu]] | align="center" | 57 | |- | 340 | [[Kullanıcı:Spanier|Spanier]] | align="center" | 57 | |- | 341 | [[Kullanıcı:LejyonerZaza|LejyonerZaza]] | align="center" | 57 | |- | 342 | [[Kullanıcı:SAL 329|SAL 329]] | align="center" | 56 | |- | 343 | [[Kullanıcı:S htk 428|S htk 428]] | align="center" | 56 | |- | 344 | [[Kullanıcı:Stml 161|Stml 161]] | align="center" | 56 | |- | 345 | [[Kullanıcı:HASAN ÖZGÜREN EML|HASAN ÖZGÜREN EML]] | align="center" | 56 | |- | 346 | [[Kullanıcı:SLesra|SLesra]] | align="center" | 56 | |- | 347 | [[Kullanıcı:SLhalit540|SLhalit540]] | align="center" | 56 | |- | 348 | [[Kullanıcı:Stultiwikia|Stultiwikia]] | align="center" | 56 | |- | 349 | [[Kullanıcı:LisafBia|LisafBia]] | align="center" | 56 | |- | 350 | [[Kullanıcı:Quinlan83|Quinlan83]] | align="center" | 56 | |- | 351 | [[Kullanıcı:Şegirt|Şegirt]] | align="center" | 56 | |- | 352 | [[Kullanıcı:TAKASUGI Shinji|TAKASUGI Shinji]] | align="center" | 55 | |- | 353 | [[Kullanıcı:Sarvaturi~trwiktionary|Sarvaturi~trwiktionary]] | align="center" | 55 | |- | 354 | [[Kullanıcı:Ks.Tahd|Ks.Tahd]] | align="center" | 55 | |- | 355 | [[Kullanıcı:Darkhorn~trwiktionary|Darkhorn~trwiktionary]] | align="center" | 54 | |- | 356 | [[Kullanıcı:Anlztrk|Anlztrk]] | align="center" | 54 | |- | 357 | [[Kullanıcı:Samleml özgür aydın|Samleml özgür aydın]] | align="center" | 53 | |- | 358 | [[Kullanıcı:Elvire|Elvire]] | align="center" | 53 | |- | 359 | [[Kullanıcı:İmmortalance|İmmortalance]] | align="center" | 53 | |- | 360 | [[Kullanıcı:Tehonk|Tehonk]] | align="center" | 53 | |- | 361 | [[Kullanıcı:NotBot|NotBot]] | align="center" | 52 | |- | 362 | [[Kullanıcı:SHTK.ARZU|SHTK.ARZU]] | align="center" | 52 | |- | 363 | [[Kullanıcı:SLOĞUZHAN|SLOĞUZHAN]] | align="center" | 52 | |- | 364 | [[Kullanıcı:WikimediaNotifier|WikimediaNotifier]] | align="center" | 52 | |- | 365 | [[Kullanıcı:Gufosowa|Gufosowa]] | align="center" | 52 | |- | 366 | [[Kullanıcı:たまほめ|たまほめ]] | align="center" | 51 | |- | 367 | [[Kullanıcı:Tembelejderha|Tembelejderha]] | align="center" | 50 | |- | 368 | [[Kullanıcı:Kml Nurcan|Kml Nurcan]] | align="center" | 50 | |- | 369 | [[Kullanıcı:Elton|Elton]] | align="center" | 50 | |- | 370 | [[Kullanıcı:Ozgurhatic|Ozgurhatic]] | align="center" | 50 | |- | 371 | [[Kullanıcı:Tıbbiye|Tıbbiye]] | align="center" | 50 | |- | 372 | [[Kullanıcı:Sepkenki|Sepkenki]] | align="center" | 50 | |- | 373 | [[Kullanıcı:Świętokrzyskie3|Świętokrzyskie3]] | align="center" | 50 | |- | 374 | [[Kullanıcı:Stml 188|Stml 188]] | align="center" | 48 | |- | 375 | [[Kullanıcı:Maderibeyza|Maderibeyza]] | align="center" | 48 | |- | 376 | [[Kullanıcı:Müftülükarif|Müftülükarif]] | align="center" | 48 | |- | 377 | [[Kullanıcı:Spl908455|Spl908455]] | align="center" | 48 | |- | 378 | [[Kullanıcı:Gökçe Yörük|Gökçe Yörük]] | align="center" | 48 | |- | 379 | [[Kullanıcı:Greywolf28|Greywolf28]] | align="center" | 48 | |- | 380 | [[Kullanıcı:Sal ruveyda|Sal ruveyda]] | align="center" | 47 | |- | 381 | [[Kullanıcı:S htk 145|S htk 145]] | align="center" | 47 | |- | 382 | [[Kullanıcı:Cmrncntn|Cmrncntn]] | align="center" | 47 | |- | 383 | [[Kullanıcı:Anon0004|Anon0004]] | align="center" | 47 | |- | 384 | [[Kullanıcı:Doruk Salancı~trwiktionary|Doruk Salancı~trwiktionary]] | align="center" | 46 | |- | 385 | [[Kullanıcı:Seml abdullah ege|Seml abdullah ege]] | align="center" | 46 | |- | 386 | [[Kullanıcı:SACAK ALİFATİH|SACAK ALİFATİH]] | align="center" | 46 | |- | 387 | [[Kullanıcı:Adml polat çelik 156|Adml polat çelik 156]] | align="center" | 46 | |- | 388 | [[Kullanıcı:Luckas Blade|Luckas Blade]] | align="center" | 46 | |- | 389 | [[Kullanıcı:BurstPower|BurstPower]] | align="center" | 46 | |- | 390 | [[Kullanıcı:Lord Leatherface~trwiktionary|Lord Leatherface~trwiktionary]] | align="center" | 45 | |- | 391 | [[Kullanıcı:Mambet|Mambet]] | align="center" | 45 | |- | 392 | [[Kullanıcı:Öz Türkçe|Öz Türkçe]] | align="center" | 45 | |- | 393 | [[Kullanıcı:JAn Dudík|JAn Dudík]] | align="center" | 45 | |- | 394 | [[Kullanıcı:Billinghurst|Billinghurst]] | align="center" | 45 | |- | 395 | [[Kullanıcı:Praxidicae|Praxidicae]] | align="center" | 45 | |- | 396 | [[Kullanıcı:MathXplore|MathXplore]] | align="center" | 45 | |- | 397 | [[Kullanıcı:Etimoloji|Etimoloji]] | align="center" | 45 | |- | 398 | [[Kullanıcı:Zbutie3.14|Zbutie3.14]] | align="center" | 45 | |- | 399 | [[Kullanıcı:Brightt11|Brightt11]] | align="center" | 45 | |- | 400 | [[Kullanıcı:Sunshine23|Sunshine23]] | align="center" | 44 | |- | 401 | [[Kullanıcı:BD2412|BD2412]] | align="center" | 44 | |- | 402 | [[Kullanıcı:Wisar12|Wisar12]] | align="center" | 44 | |- | 403 | [[Kullanıcı:Turkittihadcemiyeti|Turkittihadcemiyeti]] | align="center" | 44 | |- | 404 | [[Kullanıcı:Hoo man|Hoo man]] | align="center" | 43 | |- | 405 | [[Kullanıcı:Ghybu|Ghybu]] | align="center" | 43 | |- | 406 | [[Kullanıcı:Zolgoyo|Zolgoyo]] | align="center" | 43 | |- | 407 | [[Kullanıcı:YBK4|YBK4]] | align="center" | 43 | |- | 408 | [[Kullanıcı:Aktas5561|Aktas5561]] | align="center" | 42 | |- | 409 | [[Kullanıcı:Wiki13|Wiki13]] | align="center" | 42 | |- | 410 | [[Kullanıcı:Alexander Mikhalenko|Alexander Mikhalenko]] | align="center" | 42 | |- | 411 | [[Kullanıcı:Orsev.i.o.ayşe kibaroğlu|Orsev.i.o.ayşe kibaroğlu]] | align="center" | 41 | |- | 412 | [[Kullanıcı:Stml 168|Stml 168]] | align="center" | 41 | |- | 413 | [[Kullanıcı:Sihl selim|Sihl selim]] | align="center" | 41 | |- | 414 | [[Kullanıcı:V. Doğan Günay~trwiktionary|V. Doğan Günay~trwiktionary]] | align="center" | 41 | |- | 415 | [[Kullanıcı:Filanca|Filanca]] | align="center" | 41 | |- | 416 | [[Kullanıcı:Nurettincerek|Nurettincerek]] | align="center" | 41 | |- | 417 | [[Kullanıcı:Umitduranist|Umitduranist]] | align="center" | 41 | |- | 418 | [[Kullanıcı:Wentayan|Wentayan]] | align="center" | 41 | |- | 419 | [[Kullanıcı:Abant12|Abant12]] | align="center" | 41 | |- | 420 | [[Kullanıcı:Ahmetcatalkaya|Ahmetcatalkaya]] | align="center" | 40 | |- | 421 | [[Kullanıcı:Ahulusi|Ahulusi]] | align="center" | 40 | |- | 422 | [[Kullanıcı:Savh|Savh]] | align="center" | 40 | |- | 423 | [[Kullanıcı:FocalPoint|FocalPoint]] | align="center" | 40 | |- | 424 | [[Kullanıcı:Bulgu|Bulgu]] | align="center" | 40 | |- | 425 | [[Kullanıcı:Dijan|Dijan]] | align="center" | 39 | |- | 426 | [[Kullanıcı:Saçak fatmamandirali|Saçak fatmamandirali]] | align="center" | 39 | |- | 427 | [[Kullanıcı:Yabancı|Yabancı]] | align="center" | 39 | |- | 428 | [[Kullanıcı:Cekli829|Cekli829]] | align="center" | 39 | |- | 429 | [[Kullanıcı:Vanished user Xorisdtbdfgonugyfs|Vanished user Xorisdtbdfgonugyfs]] | align="center" | 39 | |- | 430 | [[Kullanıcı:Mathonius|Mathonius]] | align="center" | 39 | |- | 431 | [[Kullanıcı:Vincent Vega|Vincent Vega]] | align="center" | 39 | |- | 432 | [[Kullanıcı:Samuele2002|Samuele2002]] | align="center" | 39 | |- | 433 | [[Kullanıcı:CanerDemirci281993|CanerDemirci281993]] | align="center" | 39 | |- | 434 | [[Kullanıcı:Eusbarbosa|Eusbarbosa]] | align="center" | 38 | |- | 435 | [[Kullanıcı:Açak osman|Açak osman]] | align="center" | 38 | |- | 436 | [[Kullanıcı:Araklı|Araklı]] | align="center" | 38 | |- | 437 | [[Kullanıcı:Tapio Toola|Tapio Toola]] | align="center" | 38 | |- | 438 | [[Kullanıcı:Oylm mat|Oylm mat]] | align="center" | 37 | |- | 439 | [[Kullanıcı:Yalhi|Yalhi]] | align="center" | 37 | |- | 440 | [[Kullanıcı:Admlmuhammet alican|Admlmuhammet alican]] | align="center" | 37 | |- | 441 | [[Kullanıcı:SLHakan|SLHakan]] | align="center" | 37 | |- | 442 | [[Kullanıcı:JackPotte|JackPotte]] | align="center" | 37 | |- | 443 | [[Kullanıcı:Onkaimeon|Onkaimeon]] | align="center" | 37 | |- | 444 | [[Kullanıcı:Vanished user 127237|Vanished user 127237]] | align="center" | 37 | |- | 445 | [[Kullanıcı:Aabdullayev851|Aabdullayev851]] | align="center" | 37 | |- | 446 | [[Kullanıcı:Wooze|Wooze]] | align="center" | 37 | |- | 447 | [[Kullanıcı:Intolerable situation|Intolerable situation]] | align="center" | 37 | |- | 448 | [[Kullanıcı:Ykio emelaydın|Ykio emelaydın]] | align="center" | 36 | |- | 449 | [[Kullanıcı:S htk 612|S htk 612]] | align="center" | 36 | |- | 450 | [[Kullanıcı:Flyax|Flyax]] | align="center" | 36 | |- | 451 | [[Kullanıcı:Manco Capac|Manco Capac]] | align="center" | 36 | |- | 452 | [[Kullanıcı:Joseph|Joseph]] | align="center" | 36 | |- | 453 | [[Kullanıcı:Zuzumaykut|Zuzumaykut]] | align="center" | 36 | |- | 454 | [[Kullanıcı:Goktr001|Goktr001]] | align="center" | 36 | |- | 455 | [[Kullanıcı:Rxy|Rxy]] | align="center" | 36 | |- | 456 | [[Kullanıcı:MPF|MPF]] | align="center" | 36 | |- | 457 | [[Kullanıcı:Alperen|Alperen]] | align="center" | 35 | |- | 458 | [[Kullanıcı:S htk 186|S htk 186]] | align="center" | 35 | |- | 459 | [[Kullanıcı:Yonca573|Yonca573]] | align="center" | 35 | |- | 460 | [[Kullanıcı:Pinar|Pinar]] | align="center" | 34 | |- | 461 | [[Kullanıcı:Mardetanha|Mardetanha]] | align="center" | 34 | |- | 462 | [[Kullanıcı:Nanahuatl|Nanahuatl]] | align="center" | 34 | |- | 463 | [[Kullanıcı:Yoldasso|Yoldasso]] | align="center" | 34 | |- | 464 | [[Kullanıcı:Java2002|Java2002]] | align="center" | 34 | |- | 465 | [[Kullanıcı:Hasley|Hasley]] | align="center" | 34 | |- | 466 | [[Kullanıcı:Recep Arslanbaş|Recep Arslanbaş]] | align="center" | 34 | |- | 467 | [[Kullanıcı:TugbekOlek|TugbekOlek]] | align="center" | 33 | |- | 468 | [[Kullanıcı:Vese~trwiktionary|Vese~trwiktionary]] | align="center" | 33 | |- | 469 | [[Kullanıcı:Ozyurekli|Ozyurekli]] | align="center" | 33 | |- | 470 | [[Kullanıcı:EsenBoga|EsenBoga]] | align="center" | 33 | |- | 471 | [[Kullanıcı:Golgelerim|Golgelerim]] | align="center" | 33 | |- | 472 | [[Kullanıcı:Sanya3|Sanya3]] | align="center" | 33 | |- | 473 | [[Kullanıcı:Kırmızı renk|Kırmızı renk]] | align="center" | 33 | |- | 474 | [[Kullanıcı:Stml 153|Stml 153]] | align="center" | 32 | |- | 475 | [[Kullanıcı:SLsoner|SLsoner]] | align="center" | 32 | |- | 476 | [[Kullanıcı:KoreanQuoter|KoreanQuoter]] | align="center" | 32 | |- | 477 | [[Kullanıcı:Sungurer|Sungurer]] | align="center" | 32 | |- | 478 | [[Kullanıcı:HestNewDes|HestNewDes]] | align="center" | 32 | |- | 479 | [[Kullanıcı:Sml-hanife1|Sml-hanife1]] | align="center" | 31 | |- | 480 | [[Kullanıcı:SAL 417|SAL 417]] | align="center" | 31 | |- | 481 | [[Kullanıcı:MercanX|MercanX]] | align="center" | 31 | |- | 482 | [[Kullanıcı:Kokoloc|Kokoloc]] | align="center" | 31 | |- | 483 | [[Kullanıcı:Köksarı|Köksarı]] | align="center" | 30 | |- | 484 | [[Kullanıcı:Akkiz|Akkiz]] | align="center" | 30 | |- | 485 | [[Kullanıcı:Mclovinx|Mclovinx]] | align="center" | 30 | |- | 486 | [[Kullanıcı:Talha1481|Talha1481]] | align="center" | 30 | |- | 487 | [[Kullanıcı:Kumanof|Kumanof]] | align="center" | 30 | |- | 488 | [[Kullanıcı:Tenperver|Tenperver]] | align="center" | 30 | |- | 489 | [[Kullanıcı:~2026-22795-35|~2026-22795-35]] | align="center" | 30 | |- | 490 | [[Kullanıcı:Sı 643|Sı 643]] | align="center" | 29 | |- | 491 | [[Kullanıcı:SAMLEML MURAT ÇEBİ|SAMLEML MURAT ÇEBİ]] | align="center" | 29 | |- | 492 | [[Kullanıcı:Kmlblg318|Kmlblg318]] | align="center" | 29 | |- | 493 | [[Kullanıcı:Merube 89|Merube 89]] | align="center" | 29 | |- | 494 | [[Kullanıcı:Hgav|Hgav]] | align="center" | 29 | |- | 495 | [[Kullanıcı:Alsace38|Alsace38]] | align="center" | 29 | |- | 496 | [[Kullanıcı:Dilşo Kardî|Dilşo Kardî]] | align="center" | 29 | |- | 497 | [[Kullanıcı:Ulukan|Ulukan]] | align="center" | 29 | |- | 498 | [[Kullanıcı:Kaan2121|Kaan2121]] | align="center" | 29 | |- | 499 | [[Kullanıcı:Selahattin ilhan|Selahattin ilhan]] | align="center" | 29 | |- | 500 | [[Kullanıcı:Zartatue|Zartatue]] | align="center" | 29 | |} </center> 9ib8o13dol0ghgpsgauo7l4xr60ltqs koronavirüs 0 467479 5672579 3685015 2026-06-29T20:54:15Z Satirdan kahraman 37401 TurkceMaddePanel 5672579 wikitext text/x-wiki ==Türkçe== ===Köken=== ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||ko|ro|na|vi|rüs}} ===Ad=== {{tr-ad}} [[File:Coronaviruses 004 lores.jpg|küçükresim|'''Koronavirüs.''']] #{{t|dil=tr|viroloji}} Yüksek ateş ve nefes darlığı ile tanımlanan, viral solunum yolu hastalığına sebep olan bir tür virüs. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} * {{KYK:Nişanyan}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} bskvlie50jtddgnbgku3ak4gqgcgejy απροσδόκητος 0 572248 5672762 4209024 2026-06-30T09:36:30Z MustafaCavlak 59368 /* Yunanca */ 5672762 wikitext text/x-wiki {{bak|ἀπροσδόκητος}} ==Yunanca== ===Ön ad=== {{el-ön ad|d=απροσδόκητη|n=απροσδόκητο}} # [[beklenmedik]], [[umulmadık]] #: {{eş anlamlılar|el|αιφνίδιος|αναπάντεχος|ανέλπιστος|απρόβλεπτος|απρόοπτος|απρόσμενος}} ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=απροσδόκητ}} ====Karşıt anlamlılar==== * {{b|el|αναμενόμενος}} * {{b|el|προσδοκώμενος}} ====İlgili sözcükler==== * {{b|el|απροσδόκητα}} faie07uy2ejxs5c9i0fsr5u1z9i8waf αδαμαντοπωλείο 0 605173 5672645 4553033 2026-06-29T22:29:53Z MustafaCavlak 59368 /* Ad */ 5672645 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n|αδαμαντοπωλεία}} # [[kuyumcu]] [[dükkân]]ı ====Çekimleme==== {{el-aN-ο-α-2a|αδαμαντοπωλεί}} becug8f78yn1i25bturgx4iw4vm0mrq cyanurer 0 882814 5672737 4853247 2026-06-30T08:52:39Z MustafaCavlak 59368 /* Eylem */ 5672737 wikitext text/x-wiki ==Fransızca== ===Eylem=== {{fr-eylem}} # [[siyanürlemek]] ====Çekimleme==== {{fr-er-oto}} easllueu3lgsj5j7e696el5ktix1kpc başlangıç çizgisi 0 898599 5672719 5241381 2026-06-30T06:26:58Z Satirdan kahraman 37401 TurkceMaddePanel 5672719 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|başlangıç|çizgi }} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||baş|lan|gıç|çiz|gi|si}} ===Ad=== {{tr-ad}} [[File:Starting line (Unsplash).jpg|küçükresim|Başlangıç çizgisi ]] # {{t|dil=tr|spor}} [[çıkış çizgisi]]. ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} 1r3k35s26ucmn6poc8l7b93cc0gc4p1 sıtma sivrisineği 0 923192 5672558 4910613 2026-06-29T20:33:25Z Satirdan kahraman 37401 TurkceMaddePanel 5672558 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|sıtma|sivrisinek}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||sıt|ma|siv|ri|si|ne|ği}} ===Ad=== {{tr-ad}} [[Dosya:AnophelesGambiaemosquito.jpg|küçükresim|Sıtma sivrisineği]] #{{t|dil=tr|böcekler}} Çift kanatlılardan, ince, uzun vücutlu ve dar kanatlı, dişisi sıtma asalağını insandan insana taşıyan bir eklem bacaklı türü; [[anofel]] {{belirtici|Anopheles maculipennis}}. #* "Sıtma sivrisineği genellikle güneş battıktan sonra soktuğundan sıtmalı yerlerde güneş doğmadan önce ve battıktan sonra dışarıda bulunmayınız." - Mehmet Temel ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== *{{kaynak-TDK}} aewtrmuoa6yupdtsul5wki5z4yno2p1 ανέλπιστος 0 1301311 5672763 5353923 2026-06-30T09:37:12Z MustafaCavlak 59368 /* Ön ad */ 5672763 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[umulmadık]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=ανέλπιστ}} b94zy6gxe1thoh4pa1r0cefydpy6qvo ανεπίβλεπτος 0 1301373 5672749 5353985 2026-06-30T09:24:46Z MustafaCavlak 59368 /* Ön ad */ 5672749 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[denetimsiz]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=ανεπίβλεπτ}} 20xfya9pgqgre5yvbh088rl00clkmvq απρόοπτος 0 1302058 5672761 5354670 2026-06-30T09:34:54Z MustafaCavlak 59368 /* Ön ad */ 5672761 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # öngörülmemiş olan, öngörülemeyen ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=απρόοπτ}} 7h4h1yzrwf89wvgxnszurlfupgavj5v δεκάλεπτος 0 1303243 5672752 5355856 2026-06-30T09:26:35Z MustafaCavlak 59368 5672752 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[on]] [[dakikalık]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=δεκάλεπτ}} p3q1l2lf0jvb1duanhk1iulaxcjrtcn δεκαπεντάλεπτος 0 1303250 5672750 5355863 2026-06-30T09:25:45Z MustafaCavlak 59368 /* Ön ad */ 5672750 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[on beş]] [[dakikalık]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=δεκαπεντάλεπτ}} 39ag4opaw7dcvc2i54kjbqmtsd1ep8o δίλεπτος 0 1303379 5672755 5355992 2026-06-30T09:29:48Z MustafaCavlak 59368 /* Ön ad */ 5672755 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[iki]] [[dakikalık]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=δίλεπτ}} 1x9hd0dby35zir1clhuufmmhik1f1as δίλεφτος 0 1303380 5672758 5355993 2026-06-30T09:31:48Z MustafaCavlak 59368 /* Ön ad */ 5672758 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # {{farklı|dil=el|δίλεπτος}} ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=δίλεφτ}} 9dvj9hodrpyldlvifd3iomlaus4sj7h δίστιχος 0 1303429 5672743 5356043 2026-06-30T09:16:00Z MustafaCavlak 59368 5672743 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[iki]] [[dizeli]], iki [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=δίστιχ}} 99xuggwy6h6seku0yq4bfmen6ivt7ob εικοσάλεπτος 0 1303616 5672751 5356230 2026-06-30T09:26:12Z MustafaCavlak 59368 5672751 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[yirmi]] [[dakikalık]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=εικοσάλεπτ}} 4koeaivu7ovw80f47ysnnwh2pjobkna έμμονος 0 1303701 5672684 5356315 2026-06-30T01:22:53Z MustafaCavlak 59368 /* Ön ad */ 5672684 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[takıntılı]], [[saplantılı]] # [[ısrarcı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=έμμον}} ps3z2z2ic9a7al7rd3tb32hi590t53a εξάστιχος 0 1303822 5672739 5356436 2026-06-30T09:14:11Z MustafaCavlak 59368 /* Ön ad */ 5672739 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[altı]] [[dizeli]], altı [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=εξάστιχ}} h4xtjeih62rus53qxdj2z3jlo6cn6ih επτάστιχος 0 1303932 5672748 5356546 2026-06-30T09:18:29Z MustafaCavlak 59368 /* Ön ad */ 5672748 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[yedi]] [[dizeli]], yedi [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=επτάστιχ}} 0a60qtn8595ye0kus23nhix3slalka9 ευρύτερος 0 1304099 5672682 5356713 2026-06-30T01:19:37Z MustafaCavlak 59368 /* Ön ad */ 5672682 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[daha]] [[geniş]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=ευρύτερ}} 4rq5zn700u2cudovuay6rzxzf22bdzz λιγόλεπτος 0 1304850 5672756 5357464 2026-06-30T09:30:31Z MustafaCavlak 59368 /* Ön ad */ 5672756 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # {{farklı|dil=el|ολιγόλεπτος}} ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=λιγόλεπτ}} 4ymxe9qujvk06bb1d6enxv1678h4bjw μονόλεφτος 0 1305142 5672759 5357756 2026-06-30T09:32:27Z MustafaCavlak 59368 /* Ön ad */ 5672759 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # {{farklı|dil=el|μονόλεπτος}} ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=μονόλεφτ}} rm4gwlt96l64jf21dmjpm6i16vyv4ov μονόστιχος 0 1305166 5672742 5357780 2026-06-30T09:15:27Z MustafaCavlak 59368 /* Ön ad */ 5672742 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[tek]] [[dizeli]], bir [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=μονόστιχ}} k3k4jsc8bhyyxmyx5lzt6znjotxsypt οκτάστιχος 0 1305471 5672745 5358085 2026-06-30T09:17:06Z MustafaCavlak 59368 5672745 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[sekiz]] [[dizeli]], sekiz [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=οκτάστιχ}} 7ru9axss0xbypcitncpdzunpavbdrey ολιγόλεπτος 0 1305498 5672753 5358112 2026-06-30T09:27:03Z MustafaCavlak 59368 /* Ön ad */ 5672753 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[birkaç]] [[dakikalık]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=ολιγόλεπτ}} t1t7dn9c51d3y5bobkxl6qq5czt3fm2 ολιγόστιχος 0 1305505 5672744 5358119 2026-06-30T09:16:47Z MustafaCavlak 59368 /* Ön ad */ 5672744 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[az]] sayıda [[dize]]den oluşan, az [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=ολιγόστιχ}} 09w5ec7dnfut4mqspip2l1hlx7paikg οχτάστιχος 0 1305679 5672740 5358293 2026-06-30T09:14:44Z MustafaCavlak 59368 /* Ön ad */ 5672740 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # {{farklı|dil=el|οκτάστιχος}} ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=οχτάστιχ}} 7if44rzypztd22uiad6nxcctc9z8bb1 πεντάλεπτος 0 1305863 5672757 5358477 2026-06-30T09:30:55Z MustafaCavlak 59368 /* Ön ad */ 5672757 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[beş]] [[dakikalık]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=πεντάλεπτ}} dwg7slwy2tr2p2aq933rbl7oa4epmhb πεντάστιχος 0 1305877 5672746 5358491 2026-06-30T09:17:40Z MustafaCavlak 59368 /* Ön ad */ 5672746 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[beş]] [[dizeli]], beş [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=πεντάστιχ}} n0kw4gckv8kv576b73q78m56sdd436x περίβλεφτος 0 1305899 5672760 5358513 2026-06-30T09:32:58Z MustafaCavlak 59368 /* Ön ad */ 5672760 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # {{farklı|dil=el|περίβλεπτος}} ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=περίβλεφτ}} rv4zs1kfe0him904moza2tzkmckiyyd πολύστιχος 0 1306151 5672738 5358765 2026-06-30T09:13:20Z MustafaCavlak 59368 /* Ön ad */ 5672738 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[çok]] [[dizeli]], çok [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=πολύστιχ}} 3qqtr7dyug3yepda1afj9s6rl3j6oa7 τετράστιχος 0 1306812 5672741 5359427 2026-06-30T09:15:03Z MustafaCavlak 59368 /* Ön ad */ 5672741 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[dört]] [[dizeli]], dört [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=τετράστιχ}} qv71axsu2b4pir6gdi4e93fku56d3aq τρίστιχος 0 1306954 5672747 5359569 2026-06-30T09:18:02Z MustafaCavlak 59368 /* Ön ad */ 5672747 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[üç]] [[dizeli]], üç [[satırlı]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=τρίστιχ}} kxmvg6gt06890yq11mzlcgy2jlk8qr2 τσιγγούνικος 0 1306988 5672729 5359603 2026-06-30T07:58:41Z MustafaCavlak 59368 /* Ön ad */ 5672729 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # {{farklı|dil=el|τσιγκούνικος}} ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=τσιγγούνικ}} dzl35dfprfyud16zs31xemkjjl4ovnt τσιγκούνικος 0 1306990 5672728 5359605 2026-06-30T07:57:41Z MustafaCavlak 59368 /* Ön ad */ 5672728 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[cimrilik]]le ilgili, [[cimri]], [[cimrice]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=τσιγκούνικ}} hbvxiew83b0x54prk831vp0bdzuptj9 υπέρλεπτος 0 1307054 5672754 5359669 2026-06-30T09:28:49Z MustafaCavlak 59368 /* Ön ad */ 5672754 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[fazlasıyla]] [[ince]] ====Çekimleme==== {{el-çekim-öa|çekim=ος-η-ο|kök=υπέρλεπτ}} f7c4ghndpbgy2si2fvoj1zd1swop2u8 fédéraliser 0 1455440 5672724 5510445 2026-06-30T07:49:21Z MustafaCavlak 59368 /* Fransızca */ 5672724 wikitext text/x-wiki ==Fransızca== ===Köken=== {{ek|dil=fr|fédéral|iser}} ===Eylem=== {{fr-eylem}} # [[federalleştirmek]] ====Çekimleme==== {{fr-er-oto}} g9555lb7srynfk26c6lbf8bz0xvpn00 inaugurer 0 1455841 5672731 5510851 2026-06-30T08:06:53Z MustafaCavlak 59368 /* Fransızca */ 5672731 wikitext text/x-wiki ==Fransızca== ===Köken=== Öğrenilmiş bir şekilde {{nakledilen|fr|la|inaugurō|inaugurāre}}. ===Eylem=== {{fr-eylem}} # [[tören]]le [[açmak]], [[açılış]] töreniyle [[başlatmak]] ====Çekimleme==== {{fr-er-oto}} 5sye8eltr5z4ri6v5ig5f9d20ech24u refédéraliser 0 1457050 5672725 5512086 2026-06-30T07:50:59Z MustafaCavlak 59368 /* Fransızca */ 5672725 wikitext text/x-wiki ==Fransızca== ===Köken=== {{ön ek|dil=fr|re|fédéraliser}} ===Eylem=== {{fr-eylem}} # [[yeniden]] [[federalleştirmek]] ====Çekimleme==== {{fr-er-oto}} kd7szy4k2960x4cbvqhfp6pya6cs28j ribouler 0 1457340 5672730 5512397 2026-06-30T08:04:42Z MustafaCavlak 59368 /* Fransızca */ 5672730 wikitext text/x-wiki ==Fransızca== ===Köken=== {{z|fr|rebouler}} sözcüğünden. ===Eylem=== {{fr-eylem}} # {{t|dil=fr|teklifsiz konuşma}} [[gözlerini devirmek]] ====Çekimleme==== {{fr-er-oto}} pighsj5ri5oeedxs7106ine5elmaone schuldenfrei 0 1512851 5672732 5568759 2026-06-30T08:08:00Z MustafaCavlak 59368 /* Ön ad */ 5672732 wikitext text/x-wiki ==Almanca== ===Ön ad=== {{de-ön ad|-}} # [[borçsuz]] ====Çekimleme==== {{de-kıyaslanamayan-tablo}} lafb1nor84mhbgr7l73pnyfckc0dosi Modül:ru-genel 828 1589236 5672511 5669922 2026-06-29T15:42:34Z MustafaCavlak 59368 imported from en 5672511 Scribunto text/plain local export = {} --[==[ intro: Author: Benwing; some very early work by Rua and Atitarev This module holds some commonly used functions for the Russian language. It's generally for use from other modules, not `#invoke`, although some functions can be invoked from a template (`export.iotation()`, `export.reduce_stem()`, `export.dereduce_stem()`, actually added to support calling from a bot script rather than from a user template; and `export.make_unstressed()`, called from {{tl|R:ru:Vasmer}}). There may be issues when invoking such functions from templates when transliteration is present, due to the need for the transliteration to be decomposed, as mentioned below (all strings from Wiktionary pages are normally in composed form). NOTE NOTE NOTE: All functions assume that transliteration (but not Russian) has had its acute and grave accents decomposed using `export.decompose()`. This is the first thing that should be done to all user-specified transliteration and any transliteration we compute that we expect to work with. ]==] local m_str_utils = require("Modül:string araçları") local m_table_tools = require("Modül:table tools") -- Prevents an infinite require loop since ru-translit requires a different function in this module. local m_ru_translit = require("Modül:require when needed")("Modül:ru-alfabe çeviri") local m_headword_utilities = require("Modül:require when needed")("Modül:başlık başı araçları") local m_table = require("Modül:require when needed")("Modül:table") local gsplit = m_str_utils.gsplit local split = m_str_utils.split local toNFD = mw.ustring.toNFD local u = m_str_utils.char local ufind = mw.ustring.find local ugsub = mw.ustring.gsub local ulen = m_str_utils.len local ulower = m_str_utils.lower local umatch = mw.ustring.match local unpack = unpack or table.unpack -- Lua 5.2 compatibility local usub = m_str_utils.sub local insert = table.insert local concat = table.concat local AC = u(0x0301) -- acute = ́ local GR = u(0x0300) -- grave = ̀ local CFLEX = u(0x0302) -- circumflex = ̂ local BREVE = u(0x0306) -- breve ̆ local DIA = u(0x0308) -- diaeresis = ̈ local CARON = u(0x030C) -- caron ̌ local OGONEK = u(0x0328) -- ogonek ̨ local PSEUDOVOWEL = u(0xFFF1) -- pseudovowel placeholder local PSEUDOCONS = u(0xFFF2) -- pseudoconsonant placeholder -- any stress export.stress = AC .. GR -- regex for any optional stress(s) export.opt_stress = "[" .. export.stress .. "]*" -- any accent export.accent = export.stress .. DIA .. BREVE .. CARON .. OGONEK -- regex for any optional accent(s) export.opt_accent = "[" .. export.accent .. "]*" -- any composed Cyrillic vowel with grave accent export.composed_grave_vowel = "ѐЀѝЍ" -- any Cyrillic vowel except ёЁ export.vowel_no_jo = "аАеЕиИӥӤіІїЇоОуУыЫѣѢэЭюЮяЯѵѴ" .. PSEUDOVOWEL .. export.composed_grave_vowel -- any Cyrillic vowel, including ёЁ export.vowel = export.vowel_no_jo .. "ёЁ" -- any vowel in transliteration export.tr_vowel = "aAeEěĚɛƐiIoOǒǑǫǪuUyY" .. PSEUDOVOWEL -- any consonant in transliteration, omitting "j" and the soft/hard sign export.tr_cons_no_approx = "bBcCčČdDfFgGkKlLmMnNpPrRsSšŠtTvVxXzZžŽ" .. PSEUDOCONS -- any consonant in transliteration, including soft/hard sign export.tr_cons = export.tr_cons_no_approx .. "jJʹʺ" -- regex for any consonant in transliteration, including soft/hard sign, -- optionally followed by any accent export.tr_cons_acc_re = "[" .. export.tr_cons .. "]" .. export.opt_accent -- any Cyrillic consonant except sibilants and ц export.cons_except_sib_c = "бБвВгГдДзЗйЙкКлЛмМнНпПрРсСтТфФхХъЪьЬѳѲ" .. PSEUDOCONS -- Cyrillic sibilant consonants export.sib = "жЖчЧшШщЩ" -- Cyrillic sibilant consonants and ц export.sib_c = export.sib .. "цЦ" -- any Cyrillic consonant export.cons = export.cons_except_sib_c .. export.sib_c -- Cyrillic velar consonants export.velar = "гГкКхХ" -- uppercase Cyrillic export.uppercase = "АБВГДЕЀЁЖЗИЍӤІЇЙКЛМНОПРСТУФХЦЧШЩЪЫЬѢЭЮЯѲѴ" local function ine(x) return x ~= "" and x or nil end --[==[ Apply Proto-Slavic iotation. This is the change that is affected by a Slavic -j- after a consonant. `stem` is the Cyrillic stem and `tr` its optional manual translit. If `shch` is given, т iotates to щ instead of ч. Normally return two values, the iotated Cyrillic stem and corresponding transliteration (which will be {nil} if passed in as {nil}). If invoked from a template or bot, however, the return value will be a single string; if manual transliteration is present, the return value will be a string of the form `CYRILLIC//TRANSLIT` with two slahes separating the Cyrillic from the translit. ]==] function export.iotation(stem, tr, shch) local combine_tr = false -- so this can be called from a template (or usually, a bot) if type(stem) == "table" then stem, tr, shch = ine(stem.args[1]), ine(stem.args[2]), ine(stem.args[3]) combine_tr = true end stem = ugsub(stem, "[сх]$", "ш") stem = ugsub(stem, "с[кт]$", "щ") stem = ugsub(stem, "[кц]$", "ч") -- normally "т" is iotated as "ч" but there are many verbs that are iotated with "щ" if shch == "щ" then stem = stem:gsub("т$", "щ") else stem = stem:gsub("т$", "ч") end stem = ugsub(stem, "[гдз]$", "ж") stem = ugsub(stem, "[бвмпфѳ]$", "%0л") -- ѵ is equivalent to в after certain vowels stem = ugsub(stem, "[аАеЕѐЀиИѝЍӥӤіІїЇѣѢэЭяЯ]" .. export.opt_stress .. "ѵ$", "%0л") if tr then tr = tr:gsub("[sx]$", "š") :gsub("s[kt]$", "šč") :gsub("[kc]$", "č") -- normally "т" is iotated as "ч" but there are many verbs that are iotated with "щ" if shch == "щ" then tr = tr:gsub("t$", "šč") else tr = tr:gsub("t$", "č") end tr = tr:gsub("[dgz]$", "ž") :gsub("[bfmpv]$", "%0l") end if combine_tr then return export.combine_russian_tr(stem, tr) end return stem, tr end do -- A word needs accents if it is unstressed and contains more than one -- vowel, unless it's a prefix or suffix local function word_needs_accents(word) return not (word:sub(1, 1) == "-" or word:sub(-1) == "-") and export.is_unstressed(word) and not export.is_monosyllabic(word) end -- Does a set of Cyrillic words in connected text need accents? We need to -- split by word and check each one. function export.needs_accents(text) for word in gsplit(text, "%s+") do if word_needs_accents(word) then return true end end return false end end --[==[ True if either: # A vowel is marked with explicit primary stress. # The word has a single jo in it (which doesn't have secondary stress). This is because a word with multiple jos requires explicit stress to be marked, since we can't infer where primary stress lies. `Jo` can be `ё`, `ѣ̈`, or `я̈` (e.g. `сѣ̈дла`, plural of `сѣдло́`). ]==] function export.is_stressed(word) if word:find(AC) then return true end word = toNFD(word) return ( select(2, ugsub(word, "[еѣяЕѢЯ]" .. DIA, "")) == 1 and not umatch(word, "[еѣяЕѢЯ]" .. DIA .. GR) ) end --[==[ True if a Cyrillic word requires explicit stress. ]==] function export.is_unstressed(word) return not export.is_stressed(word) end --[==[ True if Cyrillic word is stressed on the last syllable. ]==] function export.is_ending_stressed(word) return ufind(word, "[ёЁ][^" .. export.vowel .. "]*$") or ufind(word, "[" .. export.vowel .. "][́̈][^" .. export.vowel .. "]*$") end do local function word_is_multi_stressed(word) -- Allow ё along with another stress, e.g. [[трёхэта́жный]], [[гёрлфре́нд]] or [[Са́мсё]]. return ufind(word, "[" .. export.vowel .. "][́̈].*[" .. export.vowel .. "][́̈]") end --[==[ True if a Cyrillic term has two or more stresses (acute or diaeresis) in a given word. ]==] function export.is_multi_stressed(text) for word in gsplit(text, "[%s-]+") do if word_is_multi_stressed(word) then return true end end return false end end --[==[ True if Cyrillic word is stressed on the first syllable. ]==] function export.is_beginning_stressed(word) return ufind(word, "^[^" .. export.vowel .. "]*[ёЁ]") or ufind(word, "^[^" .. export.vowel .. "]*[" .. export.vowel .. "]́") end --[==[ True if Cyrillic word has no vowel. Don't treat suffixes as nonsyllabic even if they have no vowel, as they are generally added onto words with vowels. ]==] function export.is_nonsyllabic(word) return not ufind(word, "^%-") and not ufind(word, "[" .. export.vowel .. "]") end --[==[ True if Cyrillic word has no more than one vowel; includes non-syllabic stems such as `льд-`. ]==] function export.is_monosyllabic(word) return not ufind(word, "[" .. export.vowel .. "].*[" .. export.vowel .. "]") end local recomposer = { -- Cyrillic letters ["е" .. DIA] = "ё", ["Е" .. DIA] = "Ё", ["и" .. DIA] = "ӥ", ["И" .. DIA] = "Ӥ", ["и" .. BREVE] = "й", ["И" .. BREVE] = "Й", ["і" .. DIA] = "ї", ["І" .. DIA] = "Ї", -- Latin letters ["c" .. CARON] = "č", ["C" .. CARON] = "Č", ["e" .. CARON] = "ě", ["E" .. CARON] = "Ě", ["o" .. CARON] = "ǒ", ["O" .. CARON] = "Ǒ", ["o" .. OGONEK] = "ǫ", ["O" .. OGONEK] = "Ǫ", ["s" .. CARON] = "š", ["S" .. CARON] = "Š", ["z" .. CARON] = "ž", ["Z" .. CARON] = "Ž", -- used in ru-pron: ["ж" .. BREVE] = "ӂ", -- used in ru-pron ["Ж" .. BREVE] = "Ӂ", ["j" .. CFLEX] = "ĵ", ["J" .. CFLEX] = "Ĵ", ["j" .. CARON] = "ǰ", -- no composed uppercase equivalent of J-caron ["ʒ" .. CARON] = "ǯ", ["Ʒ" .. CARON] = "Ǯ", } --[==[ Decompose acute, grave, etc. on letters (esp. Latin) into individivual character + combining accent. But recompose Cyrillic and Latin characters that we want to treat as units and get caught in the crossfire. We mostly want acute and grave decomposed; perhaps should just explicitly decompose those and no others. ]==] function export.decompose(text) return (ugsub(toNFD(text), ".[" .. BREVE .. DIA .. CARON .. OGONEK .. "]", recomposer)) end function export.assert_decomposed(text) assert(not ufind(text, "[áéíóúýàèìòùỳäëïöüÿÁÉÍÓÚÝÀÈÌÒÙỲÄËÏÖÜŸ]")) end --[==[ Transliterate text and then apply acute/grave decomposition. ]==] function export.translit(text, no_include_monosyllabic_jo_accent) local jo_accent = not no_include_monosyllabic_jo_accent and "mono" or nil return export.decompose(m_ru_translit.tr(text, nil, nil, jo_accent)) end --[==[ Recompose acutes and graves into preceding vowels. Probably not necessary. ]==] function export.recompose(text) return mw.ustring.toNFC(text) end local grave_decomposer = { ["ѐ"] = "е" .. GR, ["Ѐ"] = "Е" .. GR, ["ѝ"] = "и" .. GR, ["Ѝ"] = "И" .. GR, } --[==[ Decompose precomposed Cyrillic chars w/grave accent; not necessary for acute accent as there aren't precomposed Cyrillic chars w/acute accent, and undesirable for precomposed `ё` and `Ё`. ]==] function export.decompose_grave(word) return (ugsub(word, "[ѐЀѝЍ]", grave_decomposer)) end local grave_deaccenter = { [GR] = "", -- grave accent ["ѐ"] = "е", -- composed Cyrillic chars w/grave accent ["Ѐ"] = "Е", ["ѝ"] = "и", ["Ѝ"] = "И", } local deaccenter = mw.clone(grave_deaccenter) deaccenter[AC] = "" -- acute accent --[==[ Remove acute and grave accents; don't affect composed diaeresis in `ёЁ` or uncomposed diaeresis in `-ѣ̈-` (as in plural `сѣ̈дла` of `сѣдло́`). NOTE: Translit must already be decomposed! See comment at top. ]==] function export.remove_accents(word, tr) local ru_removed = ugsub(word, "[́̀ѐЀѝЍ]", deaccenter) if not tr then return ru_removed, nil end return ru_removed, (ugsub(tr, "[" .. AC .. GR .. "]", deaccenter)) end --[==[ Remove grave accents; don't affect acute or composed diaeresis in `ёЁ` or uncomposed diaeresis in `-ѣ̈-` (as in plural `сѣ̈дла` of `сѣдло́`). NOTE: Translit must already be decomposed! See comment at top. ]==] function export.remove_grave_accents(word, tr) local ru_removed = ugsub(word, "[̀ѐЀѝЍ]", grave_deaccenter) if not tr then return ru_removed, nil end return ru_removed, (ugsub(tr, GR, "")) end --[==[ Remove acute and grave accents in monosyllabic words; don't affect diaeresis (composed or uncomposed) because it indicates a change in vowel quality, which still applies to monosyllabic words. Don't change suffixes, where a "monosyllabic" stress is still significant (e.g. `-ча́т` short masculine of `-ча́тый`, vs. `-́чат` short masculine of `-́чатый`). NOTE: Translit must already be decomposed! See comment at top. ]==] function export.remove_monosyllabic_accents(word, tr) if export.is_monosyllabic(word) and not ufind(word, "^%-") then return export.remove_accents(word, tr) else return word, tr end end local destresser = mw.clone(deaccenter) destresser["ё"] = "е" destresser["Ё"] = "Е" destresser[DIA] = "" -- diaeresis -- Subfunction of split_syllables(). On input we get sections of text consisting of CONSONANT - VOWEL - CONSONANT - -- VOWEL ... - CONSONANT, where CONSONANT consists of zero or more consonants and VOWEL consists of exactly one vowel -- plus any following accent(s); we combine these into syllables as required by split_syllables(). local function combine_captures(captures) if captures[1] and not captures[2] then return captures end local combined = {} for i = 1, (#captures - 1), 2 do insert(combined, captures[i] .. captures[i+1]) end combined[#combined] = combined[#combined] .. captures[#captures] return combined end --[==[ Split Russian text and transliteration into syllables. Syllables end with vowel + accent(s), except for the last syllable, which includes any trailing consonants. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.split_syllables(ru, tr) -- Split into alternating consonant/vowel sequences, as described in -- combine_captures(). local rusyllables = combine_captures(split(ru, "([" .. export.vowel .. "]" .. export.opt_accent .. ")")) local trsyllables if tr then export.assert_decomposed(tr) trsyllables = combine_captures(split(tr, "([" .. export.tr_vowel .. "]" .. export.opt_accent .. ")")) if #rusyllables ~= #trsyllables then error("Russian " .. ru .. " doesn't have same number of syllables as translit " .. tr) end end --error(concat(rusyllables, "/") .. "(" .. #rusyllables .. (trsyllables and (") || " .. concat(trsyllables, "/") .. "(" .. #trsyllables .. ")") or "")) return rusyllables, trsyllables end --[==[ Split Russian word and transliteration into hyphen-separated components. Rejoining with `concat(..., "-")` will recover the original word. If the original word ends in a hyphen, that hyphen gets included with the preceding component(this is the only case when an individual component has a hyphen in it). ]==] function export.split_hyphens(ru, tr) local rucomponents = split(ru, "%-") if rucomponents[#rucomponents] == "" and #rucomponents > 1 then rucomponents[#rucomponents - 1] = rucomponents[#rucomponents - 1] .. "-" table.remove(rucomponents) end local trcomponents if tr then trcomponents = split(tr, "%-") if trcomponents[#trcomponents] == "" and #trcomponents > 1 then trcomponents[#trcomponents - 1] = trcomponents[#trcomponents - 1] .. "-" table.remove(trcomponents) end if #rucomponents ~= #trcomponents then error("Russian " .. ru .. " doesn't have same number of hyphenated components as translit " .. tr) end end return rucomponents, trcomponents end --[==[ Apply `j` correction, converting `je` to `e` after consonants, `jo` to `o` after a sibilant, `ju` to `u` after hard sibilant. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.j_correction(tr) tr = ugsub(tr, "([" .. export.tr_cons_no_approx .. "]" .. export.opt_accent ..")[Jj]([EeĚě])", "%1%2") tr = ugsub(tr, "([žščŽŠČ])[Jj]([Oo])", "%1%2") return (ugsub(tr, "([žšŽŠ])[Jj]([Uu])", "%1%2")) end local function make_unstressed_ru(ru) -- The following regexp has grave+acute+diaeresis after the bracket return (ugsub(ru, "[̀́̈ёЁѐЀѝЍ]", destresser)) end --[==[ Remove all stress marks (acute, grave, diaeresis). NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_unstressed(ru, tr) -- so this can be called from a template (specifically {{R:ru:Vasmer}}) if type(ru) == "table" then ru, tr = ine(ru.args[1]), ine(ru.args[2]) end if not tr then return make_unstressed_ru(ru), nil end -- In the presence of TR, we need to do things the hard way: Splitting -- into syllables and only converting Latin o to e opposite a ё. local rusyl, trsyl = export.split_syllables(ru, tr) for i=1,#rusyl do if ufind(rusyl[i], "[ёЁ]") then trsyl[i] = ugsub(trsyl[i], "[Oo]", {["O"] = "E", ["o"] = "e"}) end rusyl[i] = make_unstressed_ru(rusyl[i]) -- the following should still work as it will affect accents only trsyl[i] = make_unstressed_ru(trsyl[i]) end -- Also need to apply j correction as otherwise we'll have je after cons, etc. return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end local function remove_jo_ru(word) return (ugsub(word, "[̈ёЁ]", destresser)) end local function make_unstressed_once_ru(word) -- leave graves alone return (ugsub(word, "([́̈ёЁ])([^́̈ёЁ]*)$", function(x, rest) return destresser[x] .. rest; end, 1)) end --[==[ Remove diaeresis stress marks only. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.remove_jo(ru, tr) if not tr then return remove_jo_ru(ru), nil end -- In the presence of TR, we need to do things the hard way: Splitting -- into syllables and only converting Latin o to e opposite a ё. local rusyl, trsyl = export.split_syllables(ru, tr) for i=1,#rusyl do if ufind(rusyl[i], "[ёЁ]") then trsyl[i] = ugsub(trsyl[i], "[Oo]", {["O"] = "E", ["o"] = "e"}) end rusyl[i] = remove_jo_ru(rusyl[i]) -- the following should still work as it will affect accents only trsyl[i] = make_unstressed_once_ru(trsyl[i]) end -- Also need to apply j correction as otherwise we'll have je after cons, etc. return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end local function map_last_hyphenated_component(fn, ru, tr) if ufind(ru, "%-") then -- If there is a hyphen, do it the hard way by splitting into -- individual components and doing the last one. Otherwise we just do -- the whole string. local rucomponents, trcomponents = export.split_hyphens(ru, tr) local lastru, lasttr = fn(rucomponents[#rucomponents], trcomponents and trcomponents[#trcomponents] or nil) rucomponents[#rucomponents] = lastru ru = concat(rucomponents, "-") if trcomponents then trcomponents[#trcomponents] = lasttr tr = concat(trcomponents, "-") end return ru, tr end return fn(ru, tr) end -- Make last stressed syllable (acute or diaeresis) unstressed; leave unstressed; leave graves alone; if `NOCONCAT`, -- return individual syllables. NOTE: Translit must already be decomposed! See comment at top. local function make_unstressed_once_after_hyphen_split(ru, tr, noconcat) if not tr then return make_unstressed_once_ru(ru), nil end -- In the presence of TR, we need to do things the hard way, as with -- make_unstressed(). local rusyl, trsyl = export.split_syllables(ru, tr) for i=#rusyl,1,-1 do local stressed = export.is_stressed(rusyl[i]) if stressed then if ufind(rusyl[i], "[ёЁ]") then trsyl[i] = ugsub(trsyl[i], "[Oo]", {["O"] = "E", ["o"] = "e"}) end rusyl[i] = make_unstressed_once_ru(rusyl[i]) -- the following should still work as it will affect accents only trsyl[i] = make_unstressed_once_ru(trsyl[i]) break end end if noconcat then return rusyl, trsyl end -- Also need to apply j correction as otherwise we'll have je after cons return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end --[==[ Make last stressed syllable (acute or diaeresis) to the right of any hyphen unstressed (unless the hyphen is word-final); leave graves alone. We don't destress a syllable to the left of a hyphen unless the hyphen is word-final (i.e. a prefix). Otherwise e.g. the accents in the first part of words like ко́е-како́й and а́льфа-лу́ч won't remain. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_unstressed_once(ru, tr) return map_last_hyphenated_component(make_unstressed_once_after_hyphen_split, ru, tr) end local function make_unstressed_once_at_beginning_ru(word) -- leave graves alone return (ugsub(word, "^([^́̈ёЁ]*)([́̈ёЁ])", function(rest, x) return rest .. destresser[x]; end, 1)) end --[==[ Make first stressed syllable (acute or diaeresis) unstressed; leave graves alone; if `NOCONCAT`, return individual syllables. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_unstressed_once_at_beginning(ru, tr, noconcat) if not tr then return make_unstressed_once_at_beginning_ru(ru), nil end -- In the presence of TR, we need to do things the hard way, as with -- make_unstressed(). local rusyl, trsyl = export.split_syllables(ru, tr) for i=1,#rusyl do local stressed = export.is_stressed(rusyl[i]) if stressed then if ufind(rusyl[i], "[ёЁ]") then trsyl[i] = ugsub(trsyl[i], "[Oo]", {["O"] = "E", ["o"] = "e"}) end rusyl[i] = make_unstressed_once_at_beginning_ru(rusyl[i]) -- the following should still work as it will affect accents only trsyl[i] = make_unstressed_once_at_beginning_ru(trsyl[i]) break end end if noconcat then return rusyl, trsyl end -- Also need to apply j correction as otherwise we'll have je after cons return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end --[==[ Subfunction of `make_ending_stressed()`, `make_beginning_stressed()`, which add an acute accent to a syllable that may already have a grave accent; in such a case, remove the grave. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.correct_grave_acute_clash(word, tr) word = ugsub(word, "([̀ѐЀѝЍ])́", function(x) return grave_deaccenter[x] .. AC; end) word = ugsub(word, AC .. GR, AC) if not tr then return word, nil end tr = ugsub(tr, GR .. AC, AC) tr = ugsub(tr, AC .. GR, AC) return word, tr end local function make_ending_stressed_ru(word) -- If already ending stressed, just return word so we don't mess up ё if export.is_ending_stressed(word) then return word end -- Destress the last stressed syllable word = make_unstressed_once_ru(word) -- Add an acute to the last syllable word = ugsub(word, "([" .. export.vowel_no_jo .. "])([^" .. export.vowel .. "]*)$", "%1́%2") -- If that caused an acute and grave next to each other, remove the grave return export.correct_grave_acute_clash(word) end -- Remove the last primary stress from the word and put it on the final syllable. Leave grave accents alone except in -- the last syllable. If final syllable already has primary stress, do nothing. NOTE: Translit must already be -- decomposed! See comment at top. local function make_ending_stressed_after_hyphen_split(ru, tr) if not tr then return make_ending_stressed_ru(ru), nil end -- If already ending stressed, just return ru/tr so we don't mess up ё if export.is_ending_stressed(ru) then return ru, tr end -- Destress the last stressed syllable; pass in "noconcat" so we get -- the individual syllables back local rusyl, trsyl = make_unstressed_once_after_hyphen_split(ru, tr, "noconcat") -- Add an acute to the last syllable of both Russian and translit rusyl[#rusyl] = ugsub(rusyl[#rusyl], "([" .. export.vowel_no_jo .. "])", "%1" .. AC) trsyl[#trsyl] = ugsub(trsyl[#trsyl], "([" .. export.tr_vowel .. "])", "%1" .. AC) -- If that caused an acute and grave next to each other, remove the grave rusyl[#rusyl], trsyl[#trsyl] = export.correct_grave_acute_clash(rusyl[#rusyl], trsyl[#trsyl]) -- j correction didn't get applied in make_unstressed_once because -- we short-circuited it and made it return lists of syllables return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end --[==[ Remove the last primary stress from the portion of the word to the right of any hyphen (unless the hyphen is word-final) and put it on the final syllable. Leave grave accents alone except in the last syllable. If final syllable already has primary stress, do nothing. (See `make_unstressed_once()` for why we don't affect stresses to the left of a hyphen.) NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_ending_stressed(ru, tr) return map_last_hyphenated_component(make_ending_stressed_after_hyphen_split, ru, tr) end local function make_beginning_stressed_ru(word) -- If already beginning stressed, just return word so we don't mess up ё if export.is_beginning_stressed(word) then return word end -- Destress the first stressed syllable word = make_unstressed_once_at_beginning_ru(word) -- Add an acute to the first syllable word = ugsub(word, "^([^" .. export.vowel .. "]*)([" .. export.vowel_no_jo .. "])", "%1%2́") -- If that caused an acute and grave next to each other, remove the grave return export.correct_grave_acute_clash(word) end --[==[ Remove the first primary stress from the word and put it on the initial syllable. Leave grave accents alone except in the first syllable. If initial syllable already has primary stress, do nothing. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_beginning_stressed(ru, tr) if not tr then return make_beginning_stressed_ru(ru), nil end -- If already beginning stressed, just return ru/tr so we don't mess up ё if export.is_beginning_stressed(ru) then return ru, tr end -- Destress the first stressed syllable; pass in "noconcat" so we get -- the individual syllables back local rusyl, trsyl = export.make_unstressed_once_at_beginning(ru, tr, "noconcat") -- Add an acute to the first syllable of both Russian and translit rusyl[1] = ugsub(rusyl[1], "([" .. export.vowel_no_jo .. "])", "%1" .. AC) trsyl[1] = ugsub(trsyl[1], "([" .. export.tr_vowel .. "])", "%1" .. AC) -- If that caused an acute and grave next to each other, remove the grave rusyl[1], trsyl[1] = export.correct_grave_acute_clash(rusyl[1], trsyl[1]) -- j correction didn't get applied in make_unstressed_once_at_beginning -- because we short-circuited it and made it return lists of syllables return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end -- used for tracking and categorization local hard_cons = {"hard-cons", "cons"} local hard_vowel = {"vowel", "hard-vowel"} local i_vowel = {"i", "vowel", "soft-vowel"} local sibilant_cons = {"sibilant", "cons"} local soft_vowel = {"vowel", "soft-vowel"} local velar_cons = {"velar", "cons"} local trailing_letter_type = { ["ш"] = sibilant_cons, ["щ"] = sibilant_cons, ["ч"] = sibilant_cons, ["ж"] = sibilant_cons, ["ц"] = {"c", "cons"}, ["к"] = velar_cons, ["г"] = velar_cons, ["х"] = velar_cons, ["ь"] = {"soft-cons", "cons"}, ["ъ"] = hard_cons, ["й"] = {"palatal", "cons"}, ["а"] = hard_vowel, ["я"] = soft_vowel, ["э"] = hard_vowel, ["е"] = soft_vowel, ["ѐ"] = soft_vowel, ["ѣ"] = soft_vowel, ["и"] = i_vowel, ["ѝ"] = i_vowel, ["ӥ"] = i_vowel, ["і"] = i_vowel, ["ї"] = i_vowel, ["ѵ"] = i_vowel, ["ы"] = hard_vowel, ["о"] = hard_vowel, ["ё"] = soft_vowel, ["у"] = hard_vowel, ["ю"] = soft_vowel, } function export.get_stem_trailing_letter_type(stem) return trailing_letter_type[ulower(usub(export.remove_accents(stem), -1))] or hard_cons end --[==[ Reduce stem by eliminating the "epenthetic" vowel. Applies to nominative singular masculine 2nd-declension hard and soft, and 3rd-declension feminine in -ь (e.g. [[любовь]]). `STEM` should be the result after calling `detect_stem_type()`, but with final -й if present. Normally returns two arguments (`STEM` and `TR`), but can be called from a template or bot using `#invoke` and will return one argument (`STEM`, or `STEM//TR` if `TR` is present). Returns {nil} if unable to reduce. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.reduce_stem(stem, tr, soft_n) local pre, letter, post local pretr, lettertr, posttr local combine_tr = false -- test cases with translit: -- =p.reduce_stem("фе́ез", "fɛ́jez") -> фе́йз, fɛ́jz -- =p.reduce_stem("фе́йез", "fɛ́jez") -> фе́йз, fɛ́jz -- =p.reduce_stem("фе́без", "fɛ́bez") -> фе́бз, fɛ́bz -- =p.reduce_stem("фе́лез", "fɛ́lez") -> фе́льз, fɛ́lʹz -- =p.reduce_stem("феёз", p.decompose("fɛjóz")) -> фейз, fɛjz -- =p.reduce_stem("фейёз", p.decompose("fɛjjóz")) -> фейз, fɛjz -- =p.reduce_stem("фебёз", p.decompose("fɛbjóz")) -> фебз, fɛbz -- =p.reduce_stem("фелёз", p.decompose("fɛljóz")) -> фельз, fɛlʹz -- =p.reduce_stem("фе́бей", "fɛ́bej") -> фе́бь, fɛ́bʹ -- =p.reduce_stem("фебёй", p.decompose("fɛbjój")) -> фебь, fɛbʹ -- =p.reduce_stem("фе́ей", "fɛ́jej") -> фе́йй, fɛ́jj -- =p.reduce_stem("феёй", p.decompose("fɛjój")) -> фейй, fɛjj -- so this can be called from a template (or usually, a bot) if type(stem) == "table" then stem, tr = ine(stem.args[1]), ine(stem.args[2]) combine_tr = true end pre, letter, post = umatch(stem, "^(.*)([оОеЕёЁ])́?([" .. export.cons .. "]+)$") if not pre then return nil, nil end if tr then -- FIXME, may not be necessary to write the posttr portion as a -- consonant + zero or more consonant/accent combinations -- when will -- we ever get an accent after a consonant? That would indicate a -- failure of the decompose mechanism. pretr, lettertr, posttr = umatch(tr, "^(.*)([oOeE])́?([" .. export.tr_cons .. "][" .. export.tr_cons .. export.accent .. "]*)$") if not pretr then return nil, nil -- should not happen unless tr is really messed up end -- Remove any trailing j's on the translit stem which don't have a -- corresponding й on the Cyrillic stem. This avoids excess j's with -- cases like индонези́ец//indonɛzíjec, but retains multiple j's where -- necessary. pretr = ugsub(pretr, "[jJ]+$", function(m) return usub(m, 1, ulen(umatch(pre, "[йЙ]*$"))) end) end if letter == "О" or letter == "о" then -- FIXME, what about when the accent is on the removed letter? if post == "й" or post == "Й" then -- FIXME, is this correct? return nil, nil end letter = "" else local is_upper = ufind(post, "[" .. export.uppercase .. "]") if ufind(pre, "[" .. export.vowel .. "]́?$") then letter = is_upper and "Й" or "й" elseif post == "й" or post == "Й" then letter = is_upper and "Ь" or "ь" post = "" if posttr then posttr = "" end elseif ufind(post, "[" .. export.velar .. "]$") and ufind(pre, "[" .. export.cons_except_sib_c .. "]$") or ufind(post, "[^йЙ" .. export.velar .. "]$") and ufind(pre, "[лЛ]$") or soft_n and ufind(pre, "[нН]$") then letter = is_upper and "Ь" or "ь" else letter = "" end end stem = pre .. letter .. post if tr then tr = pretr .. export.translit(letter) .. posttr end if combine_tr then return export.combine_russian_tr(stem, tr) else return stem, tr end end --[==[ Generate the dereduced stem given `STEM` and `EPENTHETIC_STRESS` (which indicates whether the epenthetic vowel should be stressed); this is without any terminating non-syllabic ending, which is added if needed by the calling function. Normally returns two arguments (`STEM` and `TR`), but can be called from a template using `#invoke` (or by bot) and will return one argument (`STEM`, or `STEM//TR` if `TR` is present). Returns {nil} if unable to dereduce. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.dereduce_stem(stem, tr, epenthetic_stress) local combine_tr = false -- so this can be called from a template (or usually, a bot) if type(stem) == "table" then stem, tr, epenthetic_stress = ine(stem.args[1]), ine(stem.args[2]), ine(stem.args[3]) combine_tr = true end if epenthetic_stress then stem, tr = export.make_unstressed_once(stem, tr) end local pre, letter, post local pretr, lettertr, posttr -- FIXME!!! Deal with this special case --if not (z.stem_type == "soft" and _.equals(z.stress_type, {"b", "f"}) -- we should ignore asterix for 2*b and 2*f (so to process it just like 2b or 2f) -- or _.contains(z.specific, "(2)") and _.equals(z.stem_type, {"velar", "letter-ц", "vowel"})) -- and also the same for (2)-specific and 3,5,6 stem-types --then -- I think this corresponds to our -ья and -ье types, which we -- handle separately --if z.stem_type == "vowel" then -- 1). -- if _.equals(z.stress_type, {"b", "c", "e", "f", "f'", "b'" }) then -- gen_pl ending stressed -- TODO: special vars for that -- z.stems["gen_pl"] = _.replace(z.stems["gen_pl"], "ь$", "е́") -- else -- z.stems["gen_pl"] = _.replace(z.stems["gen_pl"], "ь$", "и") -- end --end pre, letter, post = umatch(stem, "^(.*)([" .. export.cons .. "])([" .. export.cons .. "])$") if tr then pretr, lettertr, posttr = umatch(tr, "^(.*)(" .. export.tr_cons_acc_re .. ")(" .. export.tr_cons_acc_re .. ")$") if pre and not pretr then return nil, nil -- should not happen unless tr is really messed up end end if pre then local is_upper = ufind(post, "[" .. export.uppercase .. "]") local epvowel if ufind(letter, "[ьйЬЙ]") then letter = "" lettertr = "" if ufind(post, "[цЦ]$") or not epenthetic_stress then epvowel = is_upper and "Е" or "е" else epvowel = is_upper and "Ё" or "ё" end elseif ufind(letter, "[" .. export.cons_except_sib_c .. "]") and ufind(post, "[" .. export.velar .. "]") or ufind(letter, "[" .. export.velar .. "]") then epvowel = is_upper and "О" or "о" elseif post == "ц" or post == "Ц" then epvowel = is_upper and "Е" or "е" elseif epenthetic_stress then if ufind(letter, "[" .. export.sib .. "]") then epvowel = is_upper and "О́" or "о́" else epvowel = is_upper and "Ё" or "ё" end else epvowel = is_upper and "Е" or "е" end assert(epvowel) stem = pre .. letter .. epvowel .. post if tr then tr = pretr .. lettertr .. export.translit(epvowel) .. posttr tr = export.j_correction(tr) end if epenthetic_stress then stem, tr = export.make_ending_stressed(stem, tr) end if combine_tr then return export.combine_russian_tr(stem, tr) else return stem, tr end end return nil, nil end --[==[ Parse an entry that potentially has final footnote symbols and initial `*` for a hypothetical entry into initial symbols, text and final symbols. ]==] function export.split_symbols(entry, do_subscript) local prefentry, finalnotes = m_table_tools.separate_notes(entry) local initnotes, text = umatch(prefentry, "(%*?)(.*)$") return initnotes, text, finalnotes end -------------------------------------------------------------------------- -- Used for manual translit -- -------------------------------------------------------------------------- --[==[ Transliterate text after removing any links. The translit is decomposed in the process. ]==] function export.translit_no_links(text) return export.translit(require("Modül:bağlantılar").remove_links(text)) end --[==[ Split a combined Cyrillic/translit string (either in the form `CYRILLIC//TRANSLIT` or just `CYRILLIC`) into its components, decompose the translit, and either return a two-element list of `CYRILLIC` and `TRANSLIT` (if `dopair` is given), or two separate return values (if `dopair` is not specified). ]==] function export.split_russian_tr(term, dopair) local ru, tr if not term:find("//") then ru = term else local splitvals = split(term, "//") if #splitvals ~= 2 then error("Must have at most one // in a Russian//translit expr: '" .. term .. "'") end ru, tr = splitvals[1], export.decompose(splitvals[2]) end if dopair then return {ru, tr} else return ru, tr end end --[==[ Combine Cyrillic and translit into a single string separated by `//`. If translit is {nil}, the return value will be the same as the passed-in Cyrillic. `ru` can be a string (which any manual translit in `tr`) or a two-element table of `{CYRILLIC, TRANSLIT}`. ]==] function export.combine_russian_tr(ru, tr) if type(ru) == "table" then ru, tr = unpack(ru) end if tr then return ru .. "//" .. tr else return ru end end local function concat_maybe_moving_notes(x, y, movenotes) if movenotes then local xentry, xnotes = m_table_tools.separate_notes(x) local yentry, ynotes = m_table_tools.separate_notes(y) return xentry .. yentry .. xnotes .. ynotes else return x .. y end end --[==[ Concatenate two Cyrillic strings `RU1` and `RU2` that may have corresponding manual transliteration `TR1` and `TR2` (which should be {nil} if there is no manual translit, and otherwise should be decomposed). If `DOPAIR`, return a two-item list of the combined Cyrillic and manual translit (which will be {nil} if both `TR1` and `TR2` are {nil}); else, return two values, the combined Cyrillic and manual translit. If `MOVENOTES`, extract any footnote symbols at the end of `RU1` and move them to the end of the concatenated string, before any footnote symbols for `RU2`; same thing goes for `TR1` and `TR2`. ]==] function export.concat_russian_tr(ru1, tr1, ru2, tr2, dopair, movenotes) local ru, tr if not tr1 and not tr2 then ru = concat_maybe_moving_notes(ru1, ru2, movenotes) else if not tr1 then tr1 = export.translit_no_links(ru1) end if not tr2 then tr2 = export.translit_no_links(ru2) end ru, tr = concat_maybe_moving_notes(ru1, ru2, movenotes), export.j_correction(concat_maybe_moving_notes(tr1, tr2, movenotes)) end if dopair then return {ru, tr} else return ru, tr end end --[==[ Concatenate two Cyrillic/translit combinations (where each combination is a two-element list of `{CYRILLIC, TRANSLIT}` where `TRANSLIT` may be nil) by individually concatenating the Cyrillic and translit portions, and return a concatenated combination as a two-element list. If the manual translit portions of both terms on entry are {nil}, the result will also have {nil} manual translit. If `MOVENOTES`, extract any footnote symbols at the end of `TERM1` and move them after the concatenated string and before any footnote symbols at the end of `TERM2`. ]==] function export.concat_paired_russian_tr(term1, term2, movenotes) assert(type(term1) == "table") assert(type(term2) == "table") local ru1, tr1 = term1[1], term1[2] local ru2, tr2 = term2[1], term2[2] return export.concat_russian_tr(ru1, tr1, ru2, tr2, "dopair", movenotes) end function export.concat_forms(forms) local joined_rutr = {} for _, form in ipairs(forms) do insert(joined_rutr, export.combine_russian_tr(form)) end return concat(joined_rutr, ",") end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, strip footnote symbols from the end of the Cyrillic and translit. ]==] function export.strip_notes_from_forms(forms) local newforms = {} for _, form in ipairs(forms) do local ru, tr = form[1], form[2] ru, _ = m_table_tools.separate_notes(ru) if tr then tr, _ = m_table_tools.separate_notes(tr) end insert(newforms, {ru, tr}) end return newforms end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, unzip into parallel lists of Cyrillic and translit. The latter list may have gaps in it. ]==] function export.unzip_forms(forms) local rulist = {} local trlist = {} for i, form in ipairs(forms) do local ru, tr = form[1], form[2] rulist[i] = ru trlist[i] = tr end return rulist, trlist end --[==[ Given parallel lists of Cyrillic and translit (where the latter list may have gaps in it), return a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`. ]==] function export.zip_forms(rulist, trlist) local forms = {} for i, ru in ipairs(rulist) do insert(forms, {ru, trlist[i]}) end return forms end local function any_forms_have_translit(forms) for _, form in ipairs(forms) do if form[2] then return true end end return false end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, combine forms with identical Cyrillic, concatenating the translit with a comma+space in between. ]==] function export.combine_translit_of_duplicate_forms(forms) if not forms[1] then return forms end -- Optimization to avoid creating a new list in the majority case when no translit exists. if not any_forms_have_translit(forms) then return forms end local newforms = {} insert(newforms, {forms[1][1], forms[1][2]}) for i = 2, #forms do local found_duplicate = false for j = 1, #newforms do -- If the Russian of the next form is the same as that of the last one, combine their translits and modify -- newforms[] in-place. Otherwise add the next form to newforms[]. Make sure to clone the form rather than -- just appending it directly since we may modify it in-place; we don't want to side-effect `forms` as -- passed in. if forms[i][1] == newforms[j][1] then local tr1 = newforms[j][2] local tr2 = forms[i][2] if not tr1 and not tr2 then -- this shouldn't normally happen else tr1 = tr1 or export.translit_no_links(newforms[j][1]) tr2 = tr2 or export.translit_no_links(forms[i][1]) if tr1 == tr2 then -- this shouldn't normally happen else newforms[j][2] = tr1 .. ", " .. tr2 end end found_duplicate = true break end end if not found_duplicate then insert(newforms, {forms[i][1], forms[i][2]}) end end return newforms end function export.any_termobjs_have_translit(termobjs) for _, termobj in ipairs(termobjs) do if termobj.tr then return true end end return false end --[==[ Given a list of term objects, where each object is a table of `{term = CYRILLIC, tr = TRANSLIT, ...}`, combine forms with identical Cyrillic and identical ancillary properties, concatenating the translit with a comma+space in between. Also recompose all transliteration. ]==] function export.combine_translit_of_duplicate_termobjs_and_recompose(termobjs) if not termobjs[1] then return termobjs end -- Optimization to avoid creating a new list in the majority case when no translit exists. if not export.any_termobjs_have_translit(termobjs) then return termobjs end local newtermobjs = {} insert(newtermobjs, m_table.shallowCopy(termobjs[1])) for i = 2, #termobjs do local found_duplicate = false for j = 1, #newtermobjs do -- If the Russian of the next termobj is the same as that of the last one, combine their translits and -- modify newtermobjs[] in-place. Otherwise add the next termobj to newtermobjs[]. Make sure to clone the -- termobj rather than just appending it directly since we may modify it in-place; we don't want to -- side-effect `termobjs` as passed in. if termobjs[i].term == newtermobjs[j].term and m_headword_utilities.termobj_ancillary_properties_equal(termobjs[i], newtermobjs[j]) then local tr1 = newtermobjs[j].tr local tr2 = termobjs[i].tr if not tr1 and not tr2 then -- this shouldn't normally happen else tr1 = tr1 or export.translit_no_links(newtermobjs[j].term) tr2 = tr2 or export.translit_no_links(termobjs[i].term) if tr1 == tr2 then -- this shouldn't normally happen else newtermobjs[j].tr = tr1 .. ", " .. tr2 end end found_duplicate = true break end end if not found_duplicate then insert(newtermobjs, m_table.shallowCopy(termobjs[i])) end end for _, newtermobj in ipairs(newtermobjs) do if newtermobj.tr then newtermobj.tr = export.recompose(newtermobj.tr) end end return newtermobjs end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, split cases where two different transliterations have been packed into a single translit field by creating two adjacent term/translit pairs. This is the opposite operation of `combine_translit_of_duplicate_forms()`. ]==] function export.split_translit_of_duplicate_forms(forms) if not forms[1] then return forms end -- Optimization to avoid creating a new list in the majority case when no translit exists. if not export.any_forms_have_translit(forms) then return forms end local newforms = {} for _, form in ipairs(forms) do local ru, tr = unpack(form) if not tr or not tr:find(",") or ru:find(",") then insert(newforms, form) else local split_trs = split(tr, ",%s*") local default_tr = export.translit_no_links(ru) for _, split_tr in ipairs(split_trs) do if split_tr == default_tr then split_tr = nil end insert(newforms, {ru, split_tr}) end end end return newforms end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, split cases where two different transliterations have been packed into a single translit field by creating two adjacent term/translit pairs. This is the opposite operation of `combine_translit_of_duplicate_forms()`. ]==] function export.split_translit_of_duplicate_termobjs_and_decompose(termobjs) if not termobjs[1] then return termobjs end -- Optimization to avoid creating a new list in the majority case when no translit exists. if not export.any_termobjs_have_translit(termobjs) then return termobjs end local newobjs = {} for _, obj in ipairs(termobjs) do local tr = obj.tr if tr then tr = export.decompose(tr) end if not tr or not tr:find(",") or obj.term:find(",[^%s]") then if not tr or tr == obj.tr then insert(newobjs, obj) else obj = m_table.shallowCopy(obj) obj.tr = tr insert(newobjs, obj) end else local term = obj.term local embedded_comma_in_term = not not term:find(",") -- If there's an embedded comma in the term, we want to split on commas not followed by a space; otherwise, -- we split on commas whether or not followed by a space. To implement "comma not followed by space", we -- can use a "frontier pattern"; the one below matches if the character after the comma is in the specified -- set (which is anything but a comma or space) and the comma itself is not in the specified set (in other -- words, it is a comma or space, which matches because it's a comma). This doesn't work correctly if there -- are two commas in a row, but that should not happen as there should not be an empty translit. local split_trs = split(tr, embedded_comma_in_term and ",%f[^,%s]" or ",%s*") local default_tr = export.translit_no_links(term) for _, split_tr in ipairs(split_trs) do if split_tr == default_tr then split_tr = nil end local newobj = m_table.shallowCopy(obj) newobj.tr = split_tr insert(newobjs, newobj) end end end return newobjs end function export.strip_ending(ru, tr, ending) local strippedru = ugsub(ru, ending .. "$", "") if strippedru == ru then error("Argument " .. ru .. " doesn't end with expected ending " .. ending) end ru = strippedru tr = export.strip_tr_ending(tr, ending) return ru, tr end function export.strip_tr_ending(tr, ending) if not tr then return nil end local endingtr = ugsub(export.translit_no_links(ending), "^([Jj])", "%1?") local strippedtr = ugsub(tr, endingtr .. "$", "") if strippedtr == tr then error("Translit " .. tr .. " doesn't end with expected ending " .. endingtr) end return strippedtr end return export 689j5be9hrnp2zpsl0xirx75ti03txr 5672512 5672511 2026-06-29T15:45:02Z MustafaCavlak 59368 5672512 Scribunto text/plain local export = {} --[==[ intro: Author: Benwing; some very early work by Rua and Atitarev This module holds some commonly used functions for the Russian language. It's generally for use from other modules, not `#invoke`, although some functions can be invoked from a template (`export.iotation()`, `export.reduce_stem()`, `export.dereduce_stem()`, actually added to support calling from a bot script rather than from a user template; and `export.make_unstressed()`, called from {{tl|R:ru:Vasmer}}). There may be issues when invoking such functions from templates when transliteration is present, due to the need for the transliteration to be decomposed, as mentioned below (all strings from Wiktionary pages are normally in composed form). NOTE NOTE NOTE: All functions assume that transliteration (but not Russian) has had its acute and grave accents decomposed using `export.decompose()`. This is the first thing that should be done to all user-specified transliteration and any transliteration we compute that we expect to work with. ]==] local m_str_utils = require("Modül:string araçları") local m_table_tools = require("Modül:table tools") -- Prevents an infinite require loop since ru-translit requires a different function in this module. local m_ru_translit = require("Modül:require when needed")("Modül:ru-alfabeçeviri") local m_headword_utilities = require("Modül:require when needed")("Modül:başlık başı araçları") local m_table = require("Modül:require when needed")("Modül:table") local gsplit = m_str_utils.gsplit local split = m_str_utils.split local toNFD = mw.ustring.toNFD local u = m_str_utils.char local ufind = mw.ustring.find local ugsub = mw.ustring.gsub local ulen = m_str_utils.len local ulower = m_str_utils.lower local umatch = mw.ustring.match local unpack = unpack or table.unpack -- Lua 5.2 compatibility local usub = m_str_utils.sub local insert = table.insert local concat = table.concat local AC = u(0x0301) -- acute = ́ local GR = u(0x0300) -- grave = ̀ local CFLEX = u(0x0302) -- circumflex = ̂ local BREVE = u(0x0306) -- breve ̆ local DIA = u(0x0308) -- diaeresis = ̈ local CARON = u(0x030C) -- caron ̌ local OGONEK = u(0x0328) -- ogonek ̨ local PSEUDOVOWEL = u(0xFFF1) -- pseudovowel placeholder local PSEUDOCONS = u(0xFFF2) -- pseudoconsonant placeholder -- any stress export.stress = AC .. GR -- regex for any optional stress(s) export.opt_stress = "[" .. export.stress .. "]*" -- any accent export.accent = export.stress .. DIA .. BREVE .. CARON .. OGONEK -- regex for any optional accent(s) export.opt_accent = "[" .. export.accent .. "]*" -- any composed Cyrillic vowel with grave accent export.composed_grave_vowel = "ѐЀѝЍ" -- any Cyrillic vowel except ёЁ export.vowel_no_jo = "аАеЕиИӥӤіІїЇоОуУыЫѣѢэЭюЮяЯѵѴ" .. PSEUDOVOWEL .. export.composed_grave_vowel -- any Cyrillic vowel, including ёЁ export.vowel = export.vowel_no_jo .. "ёЁ" -- any vowel in transliteration export.tr_vowel = "aAeEěĚɛƐiIoOǒǑǫǪuUyY" .. PSEUDOVOWEL -- any consonant in transliteration, omitting "j" and the soft/hard sign export.tr_cons_no_approx = "bBcCčČdDfFgGkKlLmMnNpPrRsSšŠtTvVxXzZžŽ" .. PSEUDOCONS -- any consonant in transliteration, including soft/hard sign export.tr_cons = export.tr_cons_no_approx .. "jJʹʺ" -- regex for any consonant in transliteration, including soft/hard sign, -- optionally followed by any accent export.tr_cons_acc_re = "[" .. export.tr_cons .. "]" .. export.opt_accent -- any Cyrillic consonant except sibilants and ц export.cons_except_sib_c = "бБвВгГдДзЗйЙкКлЛмМнНпПрРсСтТфФхХъЪьЬѳѲ" .. PSEUDOCONS -- Cyrillic sibilant consonants export.sib = "жЖчЧшШщЩ" -- Cyrillic sibilant consonants and ц export.sib_c = export.sib .. "цЦ" -- any Cyrillic consonant export.cons = export.cons_except_sib_c .. export.sib_c -- Cyrillic velar consonants export.velar = "гГкКхХ" -- uppercase Cyrillic export.uppercase = "АБВГДЕЀЁЖЗИЍӤІЇЙКЛМНОПРСТУФХЦЧШЩЪЫЬѢЭЮЯѲѴ" local function ine(x) return x ~= "" and x or nil end --[==[ Apply Proto-Slavic iotation. This is the change that is affected by a Slavic -j- after a consonant. `stem` is the Cyrillic stem and `tr` its optional manual translit. If `shch` is given, т iotates to щ instead of ч. Normally return two values, the iotated Cyrillic stem and corresponding transliteration (which will be {nil} if passed in as {nil}). If invoked from a template or bot, however, the return value will be a single string; if manual transliteration is present, the return value will be a string of the form `CYRILLIC//TRANSLIT` with two slahes separating the Cyrillic from the translit. ]==] function export.iotation(stem, tr, shch) local combine_tr = false -- so this can be called from a template (or usually, a bot) if type(stem) == "table" then stem, tr, shch = ine(stem.args[1]), ine(stem.args[2]), ine(stem.args[3]) combine_tr = true end stem = ugsub(stem, "[сх]$", "ш") stem = ugsub(stem, "с[кт]$", "щ") stem = ugsub(stem, "[кц]$", "ч") -- normally "т" is iotated as "ч" but there are many verbs that are iotated with "щ" if shch == "щ" then stem = stem:gsub("т$", "щ") else stem = stem:gsub("т$", "ч") end stem = ugsub(stem, "[гдз]$", "ж") stem = ugsub(stem, "[бвмпфѳ]$", "%0л") -- ѵ is equivalent to в after certain vowels stem = ugsub(stem, "[аАеЕѐЀиИѝЍӥӤіІїЇѣѢэЭяЯ]" .. export.opt_stress .. "ѵ$", "%0л") if tr then tr = tr:gsub("[sx]$", "š") :gsub("s[kt]$", "šč") :gsub("[kc]$", "č") -- normally "т" is iotated as "ч" but there are many verbs that are iotated with "щ" if shch == "щ" then tr = tr:gsub("t$", "šč") else tr = tr:gsub("t$", "č") end tr = tr:gsub("[dgz]$", "ž") :gsub("[bfmpv]$", "%0l") end if combine_tr then return export.combine_russian_tr(stem, tr) end return stem, tr end do -- A word needs accents if it is unstressed and contains more than one -- vowel, unless it's a prefix or suffix local function word_needs_accents(word) return not (word:sub(1, 1) == "-" or word:sub(-1) == "-") and export.is_unstressed(word) and not export.is_monosyllabic(word) end -- Does a set of Cyrillic words in connected text need accents? We need to -- split by word and check each one. function export.needs_accents(text) for word in gsplit(text, "%s+") do if word_needs_accents(word) then return true end end return false end end --[==[ True if either: # A vowel is marked with explicit primary stress. # The word has a single jo in it (which doesn't have secondary stress). This is because a word with multiple jos requires explicit stress to be marked, since we can't infer where primary stress lies. `Jo` can be `ё`, `ѣ̈`, or `я̈` (e.g. `сѣ̈дла`, plural of `сѣдло́`). ]==] function export.is_stressed(word) if word:find(AC) then return true end word = toNFD(word) return ( select(2, ugsub(word, "[еѣяЕѢЯ]" .. DIA, "")) == 1 and not umatch(word, "[еѣяЕѢЯ]" .. DIA .. GR) ) end --[==[ True if a Cyrillic word requires explicit stress. ]==] function export.is_unstressed(word) return not export.is_stressed(word) end --[==[ True if Cyrillic word is stressed on the last syllable. ]==] function export.is_ending_stressed(word) return ufind(word, "[ёЁ][^" .. export.vowel .. "]*$") or ufind(word, "[" .. export.vowel .. "][́̈][^" .. export.vowel .. "]*$") end do local function word_is_multi_stressed(word) -- Allow ё along with another stress, e.g. [[трёхэта́жный]], [[гёрлфре́нд]] or [[Са́мсё]]. return ufind(word, "[" .. export.vowel .. "][́̈].*[" .. export.vowel .. "][́̈]") end --[==[ True if a Cyrillic term has two or more stresses (acute or diaeresis) in a given word. ]==] function export.is_multi_stressed(text) for word in gsplit(text, "[%s-]+") do if word_is_multi_stressed(word) then return true end end return false end end --[==[ True if Cyrillic word is stressed on the first syllable. ]==] function export.is_beginning_stressed(word) return ufind(word, "^[^" .. export.vowel .. "]*[ёЁ]") or ufind(word, "^[^" .. export.vowel .. "]*[" .. export.vowel .. "]́") end --[==[ True if Cyrillic word has no vowel. Don't treat suffixes as nonsyllabic even if they have no vowel, as they are generally added onto words with vowels. ]==] function export.is_nonsyllabic(word) return not ufind(word, "^%-") and not ufind(word, "[" .. export.vowel .. "]") end --[==[ True if Cyrillic word has no more than one vowel; includes non-syllabic stems such as `льд-`. ]==] function export.is_monosyllabic(word) return not ufind(word, "[" .. export.vowel .. "].*[" .. export.vowel .. "]") end local recomposer = { -- Cyrillic letters ["е" .. DIA] = "ё", ["Е" .. DIA] = "Ё", ["и" .. DIA] = "ӥ", ["И" .. DIA] = "Ӥ", ["и" .. BREVE] = "й", ["И" .. BREVE] = "Й", ["і" .. DIA] = "ї", ["І" .. DIA] = "Ї", -- Latin letters ["c" .. CARON] = "č", ["C" .. CARON] = "Č", ["e" .. CARON] = "ě", ["E" .. CARON] = "Ě", ["o" .. CARON] = "ǒ", ["O" .. CARON] = "Ǒ", ["o" .. OGONEK] = "ǫ", ["O" .. OGONEK] = "Ǫ", ["s" .. CARON] = "š", ["S" .. CARON] = "Š", ["z" .. CARON] = "ž", ["Z" .. CARON] = "Ž", -- used in ru-pron: ["ж" .. BREVE] = "ӂ", -- used in ru-pron ["Ж" .. BREVE] = "Ӂ", ["j" .. CFLEX] = "ĵ", ["J" .. CFLEX] = "Ĵ", ["j" .. CARON] = "ǰ", -- no composed uppercase equivalent of J-caron ["ʒ" .. CARON] = "ǯ", ["Ʒ" .. CARON] = "Ǯ", } --[==[ Decompose acute, grave, etc. on letters (esp. Latin) into individivual character + combining accent. But recompose Cyrillic and Latin characters that we want to treat as units and get caught in the crossfire. We mostly want acute and grave decomposed; perhaps should just explicitly decompose those and no others. ]==] function export.decompose(text) return (ugsub(toNFD(text), ".[" .. BREVE .. DIA .. CARON .. OGONEK .. "]", recomposer)) end function export.assert_decomposed(text) assert(not ufind(text, "[áéíóúýàèìòùỳäëïöüÿÁÉÍÓÚÝÀÈÌÒÙỲÄËÏÖÜŸ]")) end --[==[ Transliterate text and then apply acute/grave decomposition. ]==] function export.translit(text, no_include_monosyllabic_jo_accent) local jo_accent = not no_include_monosyllabic_jo_accent and "mono" or nil return export.decompose(m_ru_translit.tr(text, nil, nil, jo_accent)) end --[==[ Recompose acutes and graves into preceding vowels. Probably not necessary. ]==] function export.recompose(text) return mw.ustring.toNFC(text) end local grave_decomposer = { ["ѐ"] = "е" .. GR, ["Ѐ"] = "Е" .. GR, ["ѝ"] = "и" .. GR, ["Ѝ"] = "И" .. GR, } --[==[ Decompose precomposed Cyrillic chars w/grave accent; not necessary for acute accent as there aren't precomposed Cyrillic chars w/acute accent, and undesirable for precomposed `ё` and `Ё`. ]==] function export.decompose_grave(word) return (ugsub(word, "[ѐЀѝЍ]", grave_decomposer)) end local grave_deaccenter = { [GR] = "", -- grave accent ["ѐ"] = "е", -- composed Cyrillic chars w/grave accent ["Ѐ"] = "Е", ["ѝ"] = "и", ["Ѝ"] = "И", } local deaccenter = mw.clone(grave_deaccenter) deaccenter[AC] = "" -- acute accent --[==[ Remove acute and grave accents; don't affect composed diaeresis in `ёЁ` or uncomposed diaeresis in `-ѣ̈-` (as in plural `сѣ̈дла` of `сѣдло́`). NOTE: Translit must already be decomposed! See comment at top. ]==] function export.remove_accents(word, tr) local ru_removed = ugsub(word, "[́̀ѐЀѝЍ]", deaccenter) if not tr then return ru_removed, nil end return ru_removed, (ugsub(tr, "[" .. AC .. GR .. "]", deaccenter)) end --[==[ Remove grave accents; don't affect acute or composed diaeresis in `ёЁ` or uncomposed diaeresis in `-ѣ̈-` (as in plural `сѣ̈дла` of `сѣдло́`). NOTE: Translit must already be decomposed! See comment at top. ]==] function export.remove_grave_accents(word, tr) local ru_removed = ugsub(word, "[̀ѐЀѝЍ]", grave_deaccenter) if not tr then return ru_removed, nil end return ru_removed, (ugsub(tr, GR, "")) end --[==[ Remove acute and grave accents in monosyllabic words; don't affect diaeresis (composed or uncomposed) because it indicates a change in vowel quality, which still applies to monosyllabic words. Don't change suffixes, where a "monosyllabic" stress is still significant (e.g. `-ча́т` short masculine of `-ча́тый`, vs. `-́чат` short masculine of `-́чатый`). NOTE: Translit must already be decomposed! See comment at top. ]==] function export.remove_monosyllabic_accents(word, tr) if export.is_monosyllabic(word) and not ufind(word, "^%-") then return export.remove_accents(word, tr) else return word, tr end end local destresser = mw.clone(deaccenter) destresser["ё"] = "е" destresser["Ё"] = "Е" destresser[DIA] = "" -- diaeresis -- Subfunction of split_syllables(). On input we get sections of text consisting of CONSONANT - VOWEL - CONSONANT - -- VOWEL ... - CONSONANT, where CONSONANT consists of zero or more consonants and VOWEL consists of exactly one vowel -- plus any following accent(s); we combine these into syllables as required by split_syllables(). local function combine_captures(captures) if captures[1] and not captures[2] then return captures end local combined = {} for i = 1, (#captures - 1), 2 do insert(combined, captures[i] .. captures[i+1]) end combined[#combined] = combined[#combined] .. captures[#captures] return combined end --[==[ Split Russian text and transliteration into syllables. Syllables end with vowel + accent(s), except for the last syllable, which includes any trailing consonants. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.split_syllables(ru, tr) -- Split into alternating consonant/vowel sequences, as described in -- combine_captures(). local rusyllables = combine_captures(split(ru, "([" .. export.vowel .. "]" .. export.opt_accent .. ")")) local trsyllables if tr then export.assert_decomposed(tr) trsyllables = combine_captures(split(tr, "([" .. export.tr_vowel .. "]" .. export.opt_accent .. ")")) if #rusyllables ~= #trsyllables then error("Russian " .. ru .. " doesn't have same number of syllables as translit " .. tr) end end --error(concat(rusyllables, "/") .. "(" .. #rusyllables .. (trsyllables and (") || " .. concat(trsyllables, "/") .. "(" .. #trsyllables .. ")") or "")) return rusyllables, trsyllables end --[==[ Split Russian word and transliteration into hyphen-separated components. Rejoining with `concat(..., "-")` will recover the original word. If the original word ends in a hyphen, that hyphen gets included with the preceding component(this is the only case when an individual component has a hyphen in it). ]==] function export.split_hyphens(ru, tr) local rucomponents = split(ru, "%-") if rucomponents[#rucomponents] == "" and #rucomponents > 1 then rucomponents[#rucomponents - 1] = rucomponents[#rucomponents - 1] .. "-" table.remove(rucomponents) end local trcomponents if tr then trcomponents = split(tr, "%-") if trcomponents[#trcomponents] == "" and #trcomponents > 1 then trcomponents[#trcomponents - 1] = trcomponents[#trcomponents - 1] .. "-" table.remove(trcomponents) end if #rucomponents ~= #trcomponents then error("Russian " .. ru .. " doesn't have same number of hyphenated components as translit " .. tr) end end return rucomponents, trcomponents end --[==[ Apply `j` correction, converting `je` to `e` after consonants, `jo` to `o` after a sibilant, `ju` to `u` after hard sibilant. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.j_correction(tr) tr = ugsub(tr, "([" .. export.tr_cons_no_approx .. "]" .. export.opt_accent ..")[Jj]([EeĚě])", "%1%2") tr = ugsub(tr, "([žščŽŠČ])[Jj]([Oo])", "%1%2") return (ugsub(tr, "([žšŽŠ])[Jj]([Uu])", "%1%2")) end local function make_unstressed_ru(ru) -- The following regexp has grave+acute+diaeresis after the bracket return (ugsub(ru, "[̀́̈ёЁѐЀѝЍ]", destresser)) end --[==[ Remove all stress marks (acute, grave, diaeresis). NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_unstressed(ru, tr) -- so this can be called from a template (specifically {{R:ru:Vasmer}}) if type(ru) == "table" then ru, tr = ine(ru.args[1]), ine(ru.args[2]) end if not tr then return make_unstressed_ru(ru), nil end -- In the presence of TR, we need to do things the hard way: Splitting -- into syllables and only converting Latin o to e opposite a ё. local rusyl, trsyl = export.split_syllables(ru, tr) for i=1,#rusyl do if ufind(rusyl[i], "[ёЁ]") then trsyl[i] = ugsub(trsyl[i], "[Oo]", {["O"] = "E", ["o"] = "e"}) end rusyl[i] = make_unstressed_ru(rusyl[i]) -- the following should still work as it will affect accents only trsyl[i] = make_unstressed_ru(trsyl[i]) end -- Also need to apply j correction as otherwise we'll have je after cons, etc. return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end local function remove_jo_ru(word) return (ugsub(word, "[̈ёЁ]", destresser)) end local function make_unstressed_once_ru(word) -- leave graves alone return (ugsub(word, "([́̈ёЁ])([^́̈ёЁ]*)$", function(x, rest) return destresser[x] .. rest; end, 1)) end --[==[ Remove diaeresis stress marks only. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.remove_jo(ru, tr) if not tr then return remove_jo_ru(ru), nil end -- In the presence of TR, we need to do things the hard way: Splitting -- into syllables and only converting Latin o to e opposite a ё. local rusyl, trsyl = export.split_syllables(ru, tr) for i=1,#rusyl do if ufind(rusyl[i], "[ёЁ]") then trsyl[i] = ugsub(trsyl[i], "[Oo]", {["O"] = "E", ["o"] = "e"}) end rusyl[i] = remove_jo_ru(rusyl[i]) -- the following should still work as it will affect accents only trsyl[i] = make_unstressed_once_ru(trsyl[i]) end -- Also need to apply j correction as otherwise we'll have je after cons, etc. return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end local function map_last_hyphenated_component(fn, ru, tr) if ufind(ru, "%-") then -- If there is a hyphen, do it the hard way by splitting into -- individual components and doing the last one. Otherwise we just do -- the whole string. local rucomponents, trcomponents = export.split_hyphens(ru, tr) local lastru, lasttr = fn(rucomponents[#rucomponents], trcomponents and trcomponents[#trcomponents] or nil) rucomponents[#rucomponents] = lastru ru = concat(rucomponents, "-") if trcomponents then trcomponents[#trcomponents] = lasttr tr = concat(trcomponents, "-") end return ru, tr end return fn(ru, tr) end -- Make last stressed syllable (acute or diaeresis) unstressed; leave unstressed; leave graves alone; if `NOCONCAT`, -- return individual syllables. NOTE: Translit must already be decomposed! See comment at top. local function make_unstressed_once_after_hyphen_split(ru, tr, noconcat) if not tr then return make_unstressed_once_ru(ru), nil end -- In the presence of TR, we need to do things the hard way, as with -- make_unstressed(). local rusyl, trsyl = export.split_syllables(ru, tr) for i=#rusyl,1,-1 do local stressed = export.is_stressed(rusyl[i]) if stressed then if ufind(rusyl[i], "[ёЁ]") then trsyl[i] = ugsub(trsyl[i], "[Oo]", {["O"] = "E", ["o"] = "e"}) end rusyl[i] = make_unstressed_once_ru(rusyl[i]) -- the following should still work as it will affect accents only trsyl[i] = make_unstressed_once_ru(trsyl[i]) break end end if noconcat then return rusyl, trsyl end -- Also need to apply j correction as otherwise we'll have je after cons return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end --[==[ Make last stressed syllable (acute or diaeresis) to the right of any hyphen unstressed (unless the hyphen is word-final); leave graves alone. We don't destress a syllable to the left of a hyphen unless the hyphen is word-final (i.e. a prefix). Otherwise e.g. the accents in the first part of words like ко́е-како́й and а́льфа-лу́ч won't remain. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_unstressed_once(ru, tr) return map_last_hyphenated_component(make_unstressed_once_after_hyphen_split, ru, tr) end local function make_unstressed_once_at_beginning_ru(word) -- leave graves alone return (ugsub(word, "^([^́̈ёЁ]*)([́̈ёЁ])", function(rest, x) return rest .. destresser[x]; end, 1)) end --[==[ Make first stressed syllable (acute or diaeresis) unstressed; leave graves alone; if `NOCONCAT`, return individual syllables. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_unstressed_once_at_beginning(ru, tr, noconcat) if not tr then return make_unstressed_once_at_beginning_ru(ru), nil end -- In the presence of TR, we need to do things the hard way, as with -- make_unstressed(). local rusyl, trsyl = export.split_syllables(ru, tr) for i=1,#rusyl do local stressed = export.is_stressed(rusyl[i]) if stressed then if ufind(rusyl[i], "[ёЁ]") then trsyl[i] = ugsub(trsyl[i], "[Oo]", {["O"] = "E", ["o"] = "e"}) end rusyl[i] = make_unstressed_once_at_beginning_ru(rusyl[i]) -- the following should still work as it will affect accents only trsyl[i] = make_unstressed_once_at_beginning_ru(trsyl[i]) break end end if noconcat then return rusyl, trsyl end -- Also need to apply j correction as otherwise we'll have je after cons return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end --[==[ Subfunction of `make_ending_stressed()`, `make_beginning_stressed()`, which add an acute accent to a syllable that may already have a grave accent; in such a case, remove the grave. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.correct_grave_acute_clash(word, tr) word = ugsub(word, "([̀ѐЀѝЍ])́", function(x) return grave_deaccenter[x] .. AC; end) word = ugsub(word, AC .. GR, AC) if not tr then return word, nil end tr = ugsub(tr, GR .. AC, AC) tr = ugsub(tr, AC .. GR, AC) return word, tr end local function make_ending_stressed_ru(word) -- If already ending stressed, just return word so we don't mess up ё if export.is_ending_stressed(word) then return word end -- Destress the last stressed syllable word = make_unstressed_once_ru(word) -- Add an acute to the last syllable word = ugsub(word, "([" .. export.vowel_no_jo .. "])([^" .. export.vowel .. "]*)$", "%1́%2") -- If that caused an acute and grave next to each other, remove the grave return export.correct_grave_acute_clash(word) end -- Remove the last primary stress from the word and put it on the final syllable. Leave grave accents alone except in -- the last syllable. If final syllable already has primary stress, do nothing. NOTE: Translit must already be -- decomposed! See comment at top. local function make_ending_stressed_after_hyphen_split(ru, tr) if not tr then return make_ending_stressed_ru(ru), nil end -- If already ending stressed, just return ru/tr so we don't mess up ё if export.is_ending_stressed(ru) then return ru, tr end -- Destress the last stressed syllable; pass in "noconcat" so we get -- the individual syllables back local rusyl, trsyl = make_unstressed_once_after_hyphen_split(ru, tr, "noconcat") -- Add an acute to the last syllable of both Russian and translit rusyl[#rusyl] = ugsub(rusyl[#rusyl], "([" .. export.vowel_no_jo .. "])", "%1" .. AC) trsyl[#trsyl] = ugsub(trsyl[#trsyl], "([" .. export.tr_vowel .. "])", "%1" .. AC) -- If that caused an acute and grave next to each other, remove the grave rusyl[#rusyl], trsyl[#trsyl] = export.correct_grave_acute_clash(rusyl[#rusyl], trsyl[#trsyl]) -- j correction didn't get applied in make_unstressed_once because -- we short-circuited it and made it return lists of syllables return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end --[==[ Remove the last primary stress from the portion of the word to the right of any hyphen (unless the hyphen is word-final) and put it on the final syllable. Leave grave accents alone except in the last syllable. If final syllable already has primary stress, do nothing. (See `make_unstressed_once()` for why we don't affect stresses to the left of a hyphen.) NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_ending_stressed(ru, tr) return map_last_hyphenated_component(make_ending_stressed_after_hyphen_split, ru, tr) end local function make_beginning_stressed_ru(word) -- If already beginning stressed, just return word so we don't mess up ё if export.is_beginning_stressed(word) then return word end -- Destress the first stressed syllable word = make_unstressed_once_at_beginning_ru(word) -- Add an acute to the first syllable word = ugsub(word, "^([^" .. export.vowel .. "]*)([" .. export.vowel_no_jo .. "])", "%1%2́") -- If that caused an acute and grave next to each other, remove the grave return export.correct_grave_acute_clash(word) end --[==[ Remove the first primary stress from the word and put it on the initial syllable. Leave grave accents alone except in the first syllable. If initial syllable already has primary stress, do nothing. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.make_beginning_stressed(ru, tr) if not tr then return make_beginning_stressed_ru(ru), nil end -- If already beginning stressed, just return ru/tr so we don't mess up ё if export.is_beginning_stressed(ru) then return ru, tr end -- Destress the first stressed syllable; pass in "noconcat" so we get -- the individual syllables back local rusyl, trsyl = export.make_unstressed_once_at_beginning(ru, tr, "noconcat") -- Add an acute to the first syllable of both Russian and translit rusyl[1] = ugsub(rusyl[1], "([" .. export.vowel_no_jo .. "])", "%1" .. AC) trsyl[1] = ugsub(trsyl[1], "([" .. export.tr_vowel .. "])", "%1" .. AC) -- If that caused an acute and grave next to each other, remove the grave rusyl[1], trsyl[1] = export.correct_grave_acute_clash(rusyl[1], trsyl[1]) -- j correction didn't get applied in make_unstressed_once_at_beginning -- because we short-circuited it and made it return lists of syllables return concat(rusyl, ""), export.j_correction(concat(trsyl, "")) end -- used for tracking and categorization local hard_cons = {"hard-cons", "cons"} local hard_vowel = {"vowel", "hard-vowel"} local i_vowel = {"i", "vowel", "soft-vowel"} local sibilant_cons = {"sibilant", "cons"} local soft_vowel = {"vowel", "soft-vowel"} local velar_cons = {"velar", "cons"} local trailing_letter_type = { ["ш"] = sibilant_cons, ["щ"] = sibilant_cons, ["ч"] = sibilant_cons, ["ж"] = sibilant_cons, ["ц"] = {"c", "cons"}, ["к"] = velar_cons, ["г"] = velar_cons, ["х"] = velar_cons, ["ь"] = {"soft-cons", "cons"}, ["ъ"] = hard_cons, ["й"] = {"palatal", "cons"}, ["а"] = hard_vowel, ["я"] = soft_vowel, ["э"] = hard_vowel, ["е"] = soft_vowel, ["ѐ"] = soft_vowel, ["ѣ"] = soft_vowel, ["и"] = i_vowel, ["ѝ"] = i_vowel, ["ӥ"] = i_vowel, ["і"] = i_vowel, ["ї"] = i_vowel, ["ѵ"] = i_vowel, ["ы"] = hard_vowel, ["о"] = hard_vowel, ["ё"] = soft_vowel, ["у"] = hard_vowel, ["ю"] = soft_vowel, } function export.get_stem_trailing_letter_type(stem) return trailing_letter_type[ulower(usub(export.remove_accents(stem), -1))] or hard_cons end --[==[ Reduce stem by eliminating the "epenthetic" vowel. Applies to nominative singular masculine 2nd-declension hard and soft, and 3rd-declension feminine in -ь (e.g. [[любовь]]). `STEM` should be the result after calling `detect_stem_type()`, but with final -й if present. Normally returns two arguments (`STEM` and `TR`), but can be called from a template or bot using `#invoke` and will return one argument (`STEM`, or `STEM//TR` if `TR` is present). Returns {nil} if unable to reduce. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.reduce_stem(stem, tr, soft_n) local pre, letter, post local pretr, lettertr, posttr local combine_tr = false -- test cases with translit: -- =p.reduce_stem("фе́ез", "fɛ́jez") -> фе́йз, fɛ́jz -- =p.reduce_stem("фе́йез", "fɛ́jez") -> фе́йз, fɛ́jz -- =p.reduce_stem("фе́без", "fɛ́bez") -> фе́бз, fɛ́bz -- =p.reduce_stem("фе́лез", "fɛ́lez") -> фе́льз, fɛ́lʹz -- =p.reduce_stem("феёз", p.decompose("fɛjóz")) -> фейз, fɛjz -- =p.reduce_stem("фейёз", p.decompose("fɛjjóz")) -> фейз, fɛjz -- =p.reduce_stem("фебёз", p.decompose("fɛbjóz")) -> фебз, fɛbz -- =p.reduce_stem("фелёз", p.decompose("fɛljóz")) -> фельз, fɛlʹz -- =p.reduce_stem("фе́бей", "fɛ́bej") -> фе́бь, fɛ́bʹ -- =p.reduce_stem("фебёй", p.decompose("fɛbjój")) -> фебь, fɛbʹ -- =p.reduce_stem("фе́ей", "fɛ́jej") -> фе́йй, fɛ́jj -- =p.reduce_stem("феёй", p.decompose("fɛjój")) -> фейй, fɛjj -- so this can be called from a template (or usually, a bot) if type(stem) == "table" then stem, tr = ine(stem.args[1]), ine(stem.args[2]) combine_tr = true end pre, letter, post = umatch(stem, "^(.*)([оОеЕёЁ])́?([" .. export.cons .. "]+)$") if not pre then return nil, nil end if tr then -- FIXME, may not be necessary to write the posttr portion as a -- consonant + zero or more consonant/accent combinations -- when will -- we ever get an accent after a consonant? That would indicate a -- failure of the decompose mechanism. pretr, lettertr, posttr = umatch(tr, "^(.*)([oOeE])́?([" .. export.tr_cons .. "][" .. export.tr_cons .. export.accent .. "]*)$") if not pretr then return nil, nil -- should not happen unless tr is really messed up end -- Remove any trailing j's on the translit stem which don't have a -- corresponding й on the Cyrillic stem. This avoids excess j's with -- cases like индонези́ец//indonɛzíjec, but retains multiple j's where -- necessary. pretr = ugsub(pretr, "[jJ]+$", function(m) return usub(m, 1, ulen(umatch(pre, "[йЙ]*$"))) end) end if letter == "О" or letter == "о" then -- FIXME, what about when the accent is on the removed letter? if post == "й" or post == "Й" then -- FIXME, is this correct? return nil, nil end letter = "" else local is_upper = ufind(post, "[" .. export.uppercase .. "]") if ufind(pre, "[" .. export.vowel .. "]́?$") then letter = is_upper and "Й" or "й" elseif post == "й" or post == "Й" then letter = is_upper and "Ь" or "ь" post = "" if posttr then posttr = "" end elseif ufind(post, "[" .. export.velar .. "]$") and ufind(pre, "[" .. export.cons_except_sib_c .. "]$") or ufind(post, "[^йЙ" .. export.velar .. "]$") and ufind(pre, "[лЛ]$") or soft_n and ufind(pre, "[нН]$") then letter = is_upper and "Ь" or "ь" else letter = "" end end stem = pre .. letter .. post if tr then tr = pretr .. export.translit(letter) .. posttr end if combine_tr then return export.combine_russian_tr(stem, tr) else return stem, tr end end --[==[ Generate the dereduced stem given `STEM` and `EPENTHETIC_STRESS` (which indicates whether the epenthetic vowel should be stressed); this is without any terminating non-syllabic ending, which is added if needed by the calling function. Normally returns two arguments (`STEM` and `TR`), but can be called from a template using `#invoke` (or by bot) and will return one argument (`STEM`, or `STEM//TR` if `TR` is present). Returns {nil} if unable to dereduce. NOTE: Translit must already be decomposed! See comment at top. ]==] function export.dereduce_stem(stem, tr, epenthetic_stress) local combine_tr = false -- so this can be called from a template (or usually, a bot) if type(stem) == "table" then stem, tr, epenthetic_stress = ine(stem.args[1]), ine(stem.args[2]), ine(stem.args[3]) combine_tr = true end if epenthetic_stress then stem, tr = export.make_unstressed_once(stem, tr) end local pre, letter, post local pretr, lettertr, posttr -- FIXME!!! Deal with this special case --if not (z.stem_type == "soft" and _.equals(z.stress_type, {"b", "f"}) -- we should ignore asterix for 2*b and 2*f (so to process it just like 2b or 2f) -- or _.contains(z.specific, "(2)") and _.equals(z.stem_type, {"velar", "letter-ц", "vowel"})) -- and also the same for (2)-specific and 3,5,6 stem-types --then -- I think this corresponds to our -ья and -ье types, which we -- handle separately --if z.stem_type == "vowel" then -- 1). -- if _.equals(z.stress_type, {"b", "c", "e", "f", "f'", "b'" }) then -- gen_pl ending stressed -- TODO: special vars for that -- z.stems["gen_pl"] = _.replace(z.stems["gen_pl"], "ь$", "е́") -- else -- z.stems["gen_pl"] = _.replace(z.stems["gen_pl"], "ь$", "и") -- end --end pre, letter, post = umatch(stem, "^(.*)([" .. export.cons .. "])([" .. export.cons .. "])$") if tr then pretr, lettertr, posttr = umatch(tr, "^(.*)(" .. export.tr_cons_acc_re .. ")(" .. export.tr_cons_acc_re .. ")$") if pre and not pretr then return nil, nil -- should not happen unless tr is really messed up end end if pre then local is_upper = ufind(post, "[" .. export.uppercase .. "]") local epvowel if ufind(letter, "[ьйЬЙ]") then letter = "" lettertr = "" if ufind(post, "[цЦ]$") or not epenthetic_stress then epvowel = is_upper and "Е" or "е" else epvowel = is_upper and "Ё" or "ё" end elseif ufind(letter, "[" .. export.cons_except_sib_c .. "]") and ufind(post, "[" .. export.velar .. "]") or ufind(letter, "[" .. export.velar .. "]") then epvowel = is_upper and "О" or "о" elseif post == "ц" or post == "Ц" then epvowel = is_upper and "Е" or "е" elseif epenthetic_stress then if ufind(letter, "[" .. export.sib .. "]") then epvowel = is_upper and "О́" or "о́" else epvowel = is_upper and "Ё" or "ё" end else epvowel = is_upper and "Е" or "е" end assert(epvowel) stem = pre .. letter .. epvowel .. post if tr then tr = pretr .. lettertr .. export.translit(epvowel) .. posttr tr = export.j_correction(tr) end if epenthetic_stress then stem, tr = export.make_ending_stressed(stem, tr) end if combine_tr then return export.combine_russian_tr(stem, tr) else return stem, tr end end return nil, nil end --[==[ Parse an entry that potentially has final footnote symbols and initial `*` for a hypothetical entry into initial symbols, text and final symbols. ]==] function export.split_symbols(entry, do_subscript) local prefentry, finalnotes = m_table_tools.separate_notes(entry) local initnotes, text = umatch(prefentry, "(%*?)(.*)$") return initnotes, text, finalnotes end -------------------------------------------------------------------------- -- Used for manual translit -- -------------------------------------------------------------------------- --[==[ Transliterate text after removing any links. The translit is decomposed in the process. ]==] function export.translit_no_links(text) return export.translit(require("Modül:bağlantılar").remove_links(text)) end --[==[ Split a combined Cyrillic/translit string (either in the form `CYRILLIC//TRANSLIT` or just `CYRILLIC`) into its components, decompose the translit, and either return a two-element list of `CYRILLIC` and `TRANSLIT` (if `dopair` is given), or two separate return values (if `dopair` is not specified). ]==] function export.split_russian_tr(term, dopair) local ru, tr if not term:find("//") then ru = term else local splitvals = split(term, "//") if #splitvals ~= 2 then error("Must have at most one // in a Russian//translit expr: '" .. term .. "'") end ru, tr = splitvals[1], export.decompose(splitvals[2]) end if dopair then return {ru, tr} else return ru, tr end end --[==[ Combine Cyrillic and translit into a single string separated by `//`. If translit is {nil}, the return value will be the same as the passed-in Cyrillic. `ru` can be a string (which any manual translit in `tr`) or a two-element table of `{CYRILLIC, TRANSLIT}`. ]==] function export.combine_russian_tr(ru, tr) if type(ru) == "table" then ru, tr = unpack(ru) end if tr then return ru .. "//" .. tr else return ru end end local function concat_maybe_moving_notes(x, y, movenotes) if movenotes then local xentry, xnotes = m_table_tools.separate_notes(x) local yentry, ynotes = m_table_tools.separate_notes(y) return xentry .. yentry .. xnotes .. ynotes else return x .. y end end --[==[ Concatenate two Cyrillic strings `RU1` and `RU2` that may have corresponding manual transliteration `TR1` and `TR2` (which should be {nil} if there is no manual translit, and otherwise should be decomposed). If `DOPAIR`, return a two-item list of the combined Cyrillic and manual translit (which will be {nil} if both `TR1` and `TR2` are {nil}); else, return two values, the combined Cyrillic and manual translit. If `MOVENOTES`, extract any footnote symbols at the end of `RU1` and move them to the end of the concatenated string, before any footnote symbols for `RU2`; same thing goes for `TR1` and `TR2`. ]==] function export.concat_russian_tr(ru1, tr1, ru2, tr2, dopair, movenotes) local ru, tr if not tr1 and not tr2 then ru = concat_maybe_moving_notes(ru1, ru2, movenotes) else if not tr1 then tr1 = export.translit_no_links(ru1) end if not tr2 then tr2 = export.translit_no_links(ru2) end ru, tr = concat_maybe_moving_notes(ru1, ru2, movenotes), export.j_correction(concat_maybe_moving_notes(tr1, tr2, movenotes)) end if dopair then return {ru, tr} else return ru, tr end end --[==[ Concatenate two Cyrillic/translit combinations (where each combination is a two-element list of `{CYRILLIC, TRANSLIT}` where `TRANSLIT` may be nil) by individually concatenating the Cyrillic and translit portions, and return a concatenated combination as a two-element list. If the manual translit portions of both terms on entry are {nil}, the result will also have {nil} manual translit. If `MOVENOTES`, extract any footnote symbols at the end of `TERM1` and move them after the concatenated string and before any footnote symbols at the end of `TERM2`. ]==] function export.concat_paired_russian_tr(term1, term2, movenotes) assert(type(term1) == "table") assert(type(term2) == "table") local ru1, tr1 = term1[1], term1[2] local ru2, tr2 = term2[1], term2[2] return export.concat_russian_tr(ru1, tr1, ru2, tr2, "dopair", movenotes) end function export.concat_forms(forms) local joined_rutr = {} for _, form in ipairs(forms) do insert(joined_rutr, export.combine_russian_tr(form)) end return concat(joined_rutr, ",") end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, strip footnote symbols from the end of the Cyrillic and translit. ]==] function export.strip_notes_from_forms(forms) local newforms = {} for _, form in ipairs(forms) do local ru, tr = form[1], form[2] ru, _ = m_table_tools.separate_notes(ru) if tr then tr, _ = m_table_tools.separate_notes(tr) end insert(newforms, {ru, tr}) end return newforms end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, unzip into parallel lists of Cyrillic and translit. The latter list may have gaps in it. ]==] function export.unzip_forms(forms) local rulist = {} local trlist = {} for i, form in ipairs(forms) do local ru, tr = form[1], form[2] rulist[i] = ru trlist[i] = tr end return rulist, trlist end --[==[ Given parallel lists of Cyrillic and translit (where the latter list may have gaps in it), return a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`. ]==] function export.zip_forms(rulist, trlist) local forms = {} for i, ru in ipairs(rulist) do insert(forms, {ru, trlist[i]}) end return forms end local function any_forms_have_translit(forms) for _, form in ipairs(forms) do if form[2] then return true end end return false end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, combine forms with identical Cyrillic, concatenating the translit with a comma+space in between. ]==] function export.combine_translit_of_duplicate_forms(forms) if not forms[1] then return forms end -- Optimization to avoid creating a new list in the majority case when no translit exists. if not any_forms_have_translit(forms) then return forms end local newforms = {} insert(newforms, {forms[1][1], forms[1][2]}) for i = 2, #forms do local found_duplicate = false for j = 1, #newforms do -- If the Russian of the next form is the same as that of the last one, combine their translits and modify -- newforms[] in-place. Otherwise add the next form to newforms[]. Make sure to clone the form rather than -- just appending it directly since we may modify it in-place; we don't want to side-effect `forms` as -- passed in. if forms[i][1] == newforms[j][1] then local tr1 = newforms[j][2] local tr2 = forms[i][2] if not tr1 and not tr2 then -- this shouldn't normally happen else tr1 = tr1 or export.translit_no_links(newforms[j][1]) tr2 = tr2 or export.translit_no_links(forms[i][1]) if tr1 == tr2 then -- this shouldn't normally happen else newforms[j][2] = tr1 .. ", " .. tr2 end end found_duplicate = true break end end if not found_duplicate then insert(newforms, {forms[i][1], forms[i][2]}) end end return newforms end function export.any_termobjs_have_translit(termobjs) for _, termobj in ipairs(termobjs) do if termobj.tr then return true end end return false end --[==[ Given a list of term objects, where each object is a table of `{term = CYRILLIC, tr = TRANSLIT, ...}`, combine forms with identical Cyrillic and identical ancillary properties, concatenating the translit with a comma+space in between. Also recompose all transliteration. ]==] function export.combine_translit_of_duplicate_termobjs_and_recompose(termobjs) if not termobjs[1] then return termobjs end -- Optimization to avoid creating a new list in the majority case when no translit exists. if not export.any_termobjs_have_translit(termobjs) then return termobjs end local newtermobjs = {} insert(newtermobjs, m_table.shallowCopy(termobjs[1])) for i = 2, #termobjs do local found_duplicate = false for j = 1, #newtermobjs do -- If the Russian of the next termobj is the same as that of the last one, combine their translits and -- modify newtermobjs[] in-place. Otherwise add the next termobj to newtermobjs[]. Make sure to clone the -- termobj rather than just appending it directly since we may modify it in-place; we don't want to -- side-effect `termobjs` as passed in. if termobjs[i].term == newtermobjs[j].term and m_headword_utilities.termobj_ancillary_properties_equal(termobjs[i], newtermobjs[j]) then local tr1 = newtermobjs[j].tr local tr2 = termobjs[i].tr if not tr1 and not tr2 then -- this shouldn't normally happen else tr1 = tr1 or export.translit_no_links(newtermobjs[j].term) tr2 = tr2 or export.translit_no_links(termobjs[i].term) if tr1 == tr2 then -- this shouldn't normally happen else newtermobjs[j].tr = tr1 .. ", " .. tr2 end end found_duplicate = true break end end if not found_duplicate then insert(newtermobjs, m_table.shallowCopy(termobjs[i])) end end for _, newtermobj in ipairs(newtermobjs) do if newtermobj.tr then newtermobj.tr = export.recompose(newtermobj.tr) end end return newtermobjs end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, split cases where two different transliterations have been packed into a single translit field by creating two adjacent term/translit pairs. This is the opposite operation of `combine_translit_of_duplicate_forms()`. ]==] function export.split_translit_of_duplicate_forms(forms) if not forms[1] then return forms end -- Optimization to avoid creating a new list in the majority case when no translit exists. if not export.any_forms_have_translit(forms) then return forms end local newforms = {} for _, form in ipairs(forms) do local ru, tr = unpack(form) if not tr or not tr:find(",") or ru:find(",") then insert(newforms, form) else local split_trs = split(tr, ",%s*") local default_tr = export.translit_no_links(ru) for _, split_tr in ipairs(split_trs) do if split_tr == default_tr then split_tr = nil end insert(newforms, {ru, split_tr}) end end end return newforms end --[==[ Given a list of forms, where each form is a two-element list of `{CYRILLIC, TRANSLIT}`, split cases where two different transliterations have been packed into a single translit field by creating two adjacent term/translit pairs. This is the opposite operation of `combine_translit_of_duplicate_forms()`. ]==] function export.split_translit_of_duplicate_termobjs_and_decompose(termobjs) if not termobjs[1] then return termobjs end -- Optimization to avoid creating a new list in the majority case when no translit exists. if not export.any_termobjs_have_translit(termobjs) then return termobjs end local newobjs = {} for _, obj in ipairs(termobjs) do local tr = obj.tr if tr then tr = export.decompose(tr) end if not tr or not tr:find(",") or obj.term:find(",[^%s]") then if not tr or tr == obj.tr then insert(newobjs, obj) else obj = m_table.shallowCopy(obj) obj.tr = tr insert(newobjs, obj) end else local term = obj.term local embedded_comma_in_term = not not term:find(",") -- If there's an embedded comma in the term, we want to split on commas not followed by a space; otherwise, -- we split on commas whether or not followed by a space. To implement "comma not followed by space", we -- can use a "frontier pattern"; the one below matches if the character after the comma is in the specified -- set (which is anything but a comma or space) and the comma itself is not in the specified set (in other -- words, it is a comma or space, which matches because it's a comma). This doesn't work correctly if there -- are two commas in a row, but that should not happen as there should not be an empty translit. local split_trs = split(tr, embedded_comma_in_term and ",%f[^,%s]" or ",%s*") local default_tr = export.translit_no_links(term) for _, split_tr in ipairs(split_trs) do if split_tr == default_tr then split_tr = nil end local newobj = m_table.shallowCopy(obj) newobj.tr = split_tr insert(newobjs, newobj) end end end return newobjs end function export.strip_ending(ru, tr, ending) local strippedru = ugsub(ru, ending .. "$", "") if strippedru == ru then error("Argument " .. ru .. " doesn't end with expected ending " .. ending) end ru = strippedru tr = export.strip_tr_ending(tr, ending) return ru, tr end function export.strip_tr_ending(tr, ending) if not tr then return nil end local endingtr = ugsub(export.translit_no_links(ending), "^([Jj])", "%1?") local strippedtr = ugsub(tr, endingtr .. "$", "") if strippedtr == tr then error("Translit " .. tr .. " doesn't end with expected ending " .. endingtr) end return strippedtr end return export cp7sa75hz7i2ntcnc8rxlbyy9fbp2bu Modül:ru-nominal 828 1589237 5672503 5669923 2026-06-29T15:24:44Z MustafaCavlak 59368 5672503 Scribunto text/plain --[[ This module holds functions shared between ru-noun and ru-adjective. ]] local export = {} local lang = require("Modül:diller").getirKodaGore("ru") local m_links = require("Modül:bağlantılar") local m_table = require("Modül:table") local com = require("Modül:ru-genel") local m_ru_translit = require("Modül:ru-alfabeçeviri") local m_table_tools = require("Modül:table tools") local u = mw.ustring.char local rfind = mw.ustring.find local rsubn = mw.ustring.gsub local unpack = unpack or table.unpack -- Lua 5.2 compatibility local usub = mw.ustring.sub local HYPMARKER = "⟐" -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end -- Insert an entry into an existing list if not already present, comparing the entry to items in the existing list -- using a key function. If entry already found, combine it into the existing entry using combine_func, a function of -- two arguments (the existing and new entries), which should return the combined entry. Return false if entry already -- found, true if new entry inserted. If combine_func not specified, the existing entry is left alone. If combine_func -- is specified, the return value will be written over the existing value (i.e. the existing list will be modified -- in-place). -- -- FIXME: General enough to consider moving to [[Module:table]]. local function insert_if_not_by_key(list, new_entry, keyfunc, combine_func) local new_entry_key = keyfunc(new_entry) for i, item in ipairs(list) do local item_key = keyfunc(item) if m_table.deepEquals(item_key, new_entry_key) then if combine_func then list[i] = combine_func(item, new_entry) end return false end end table.insert(list, new_entry) return true end -------------------------------------------------------------------------- -- Used for manual translit -- -------------------------------------------------------------------------- function export.combine_stem_and_suffix(stem, tr, suf, rules, old) local first = usub(suf, 1, 1) if rules then local conv = rules[first] if conv then local ending = usub(suf, 2) -- The following regexp is not quite the same as com.vowels. For one thing -- it includes й, which is important. It leaves out ы, which may or may not -- be important. if old and conv == "и" and rfind(ending, "^́?[аеёиійоуэюяѣ]") then conv = "і" end suf = conv .. ending end end -- If <adj> is present in the suffix, it means we need to translate it -- specially; do that now. local is_adj = rfind(suf, "<adj>") suf = rsub(suf, "<adj>", "") local suftr = is_adj and m_ru_translit.tr_adj(suf, "mono") return com.concat_russian_tr(stem, tr, suf, suftr, "dopair"), suf end -------------------------------------------------------------------------- -- Formatting forms for display -- -------------------------------------------------------------------------- -- Generate a string to substitute into a particular form in a Wiki-markup table. `forms` is the list of forms, -- generated by concat_word_forms(). `is_lemma` is true if we're formatting the entry for use in displaying the lemma -- in the declension table title. In this case, we don't include the translit, and remove monosyllabic accents from the -- Cyrillic (but not in multiword expressions). `accel_form` is the form code to speicfy in the accelerator, e.g. -- 'nom|m|s', or nil for no accelerator. `lemma_forms` is the list of {RU, TR} lemma forms for use in the accelerator, -- or nil if `accel_form` is nil. `remove_monosyllabic_accents_lemma_only` indicates that monosyllabic accents should -- be removed only in the lemma; otherwise we remove them from all forms. (FIXME: Rethink why we have this flag; we -- should be consistent.) function export.show_form(forms, is_lemma, accel_form, lemma_forms, remove_monosyllabic_accents_lemma_only) local russianvals = {} local latinvals = {} local lemmavals = {} -- First fetch the lemma forms and translit. If there are adjacent forms that have identical Russian including -- stress but different translit (e.g. азербайджа́нец with translits 'azerbajdžánec' and 'azɛrbajdžánec'), we -- combine the translits, comma-separating them. (This is necessary because there is currently only one tr= -- field per term.) We don't do this when processing the forms below; instead we handle this in a different -- and more general fashion (see below). local lemmaru, lemmatr if accel_form and lemma_forms and lemma_forms[1] ~= "-" then lemma_forms = com.combine_translit_of_duplicate_forms(com.strip_notes_from_forms(lemma_forms)) for i, form in ipairs(lemma_forms) do local ru, tr = unpack(lemma_forms[i]) ru, tr = com.remove_monosyllabic_accents(ru, tr) lemma_forms[i] = {ru, tr} end lemmaru, lemmatr = com.unzip_forms(lemma_forms) end -- Accumulate separately the Russian and transliteration into RUSSIANVALS and LATINVALS, then concatenate each down -- below. We need a fair amount of logic here: -- (1) to separate out footnote symbols; -- (2) to separate out the hypothetical marker (a footnote symbol but causes display of the Russian and translit -- in a special font); -- (3) to maybe remove monosyllabic accents; -- (4) to deduplicate repeated forms. -- We used to generate the display (HTML) as we went, but this prevented proper deduplication because the -- accelerator classes included in the HTML were different for otherwise identical forms. (Specifically, if two -- forms are the same in the Russian but different in the translit, the Russian will have different display forms -- because the translit is included in the accelerator classes.) So what we do is accumulate, separately for the -- Russian and translit, objects containing the entry (Russian or translit), the separated footnote symbols, -- whether the entry is hypothetical, and (for Russian only) the corresponding translit(s), for accelerator -- generation. As we accumulate, we duduplicate based only on comparing the entries of two objects. If we need to -- deduplicate two objects, we also need to combine their footnotes and transliteration (in the latter case, by -- comma-separating; we do this because there is only one tr= field for each term). for _, form in ipairs(forms) do local ru, tr = form[1], form[2] local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) trnotes = rsub(trnotes, HYPMARKER, "") end if (is_lemma or not remove_monosyllabic_accents_lemma_only) then ruentry, trentry = com.remove_monosyllabic_accents(ruentry, trentry) end local ishyp = rfind(runotes, HYPMARKER) if ishyp then runotes = rsub(runotes, HYPMARKER, "") end local ruobj = {entry = ruentry, tr = {trentry or true}, ishyp = ishyp, notes = runotes} if not trentry then trentry = com.translit_no_links(ruentry) end if not trnotes then trnotes = com.translit_no_links(runotes) end local trobj = {entry = trentry, ishyp = ishyp, notes = trnotes} local function keyfunc(obj) return obj.entry end local function combine_func_ru(obj1, obj2) for _, tr in ipairs(obj2.tr) do m_table.insertIfNot(obj1.tr, tr) end obj1.notes = obj1.notes .. obj2.notes obj1.ishyp = obj1.ishyp or obj2.ishyp return obj1 end local function combine_func_tr(obj1, obj2) obj1.notes = obj1.notes .. obj2.notes obj1.ishyp = obj1.ishyp or obj2.ishyp return obj1 end if is_lemma then -- m_table.insertIfNot(lemmavals, ruspan .. " (" .. trspan .. ")") insert_if_not_by_key(lemmavals, ruobj, keyfunc, combine_func_ru) else insert_if_not_by_key(russianvals, ruobj, keyfunc, combine_func_ru) insert_if_not_by_key(latinvals, trobj, keyfunc, combine_func_tr) end end -- Now finally format each object and concatenate them together. local function concatenate_ru(objs) local is_missing = false for i, obj in ipairs(objs) do local accel = nil if lemmaru then local translit = nil if #obj.tr == 1 and obj.tr[1] == true then -- no translit else for j, tr in ipairs(obj.tr) do if tr == true then obj.tr[j] = com.translit_no_links(obj.entry) end end translit = table.concat(obj.tr, ", ") end accel = {form = accel_form, translit = translit, lemma = lemmaru, lemma_translit = lemmatr} end if obj.entry == "-" and #forms == 1 then objs[i] = "&mdash;" is_missing = true end if obj.ishyp then -- no accelerator for hypothetical forms objs[i] = m_links.full_link({lang = lang, term = nil, alt = obj.entry, tr = "-"}, "hypothetical") else objs[i] = m_links.full_link({lang = lang, term = obj.entry, tr = "-", accel = accel}) end objs[i] = objs[i] .. m_table_tools.superscript_notes(obj.notes) end return table.concat(objs, ", "), is_missing end local function concatenate_tr(objs) local scriptutils = require("Module:script utilities") for i, obj in ipairs(objs) do local trspan = m_links.remove_links(obj.entry) .. m_table_tools.superscript_notes(obj.notes) if obj.ishyp then -- FIXME, in the old [[Module:ru-noun]] code, notes were omitted from hypothetical entries. Correct? objs[i] = scriptutils.tag_text(trspan, lang, require("Module:scripts").getByCode("Latn"), "hypothetical") else objs[i] = scriptutils.tag_translit(trspan, lang, "default", " style=\"color: var(--wikt-palette-grey-8,#888);\"") end end return table.concat(objs, ", ") end if is_lemma then local russian_span, is_missing = concatenate_ru(lemmavals) return russian_span else local russian_span, is_missing = concatenate_ru(russianvals) if is_missing then return russian_span end local latin_span = concatenate_tr(latinvals) return russian_span .. "<br />" .. latin_span end end -------------------------------------------------------------------------- -- Sibilant/Velar/ц rules -- -------------------------------------------------------------------------- local stressed_sibilant_rules = { ["я"] = "а", ["ы"] = "и", ["ё"] = "о́", ["ю"] = "у", } local stressed_c_rules = { ["я"] = "а", ["ё"] = "о́", ["ю"] = "у", } local unstressed_sibilant_rules = { ["я"] = "а", ["ы"] = "и", ["о"] = "е", ["ю"] = "у", } local unstressed_c_rules = { ["я"] = "а", ["о"] = "е", ["ю"] = "у", } local velar_rules = { ["ы"] = "и", } export.stressed_rules = { ["ш"] = stressed_sibilant_rules, ["щ"] = stressed_sibilant_rules, ["ч"] = stressed_sibilant_rules, ["ж"] = stressed_sibilant_rules, ["ц"] = stressed_c_rules, ["к"] = velar_rules, ["г"] = velar_rules, ["х"] = velar_rules, } export.unstressed_rules = { ["ш"] = unstressed_sibilant_rules, ["щ"] = unstressed_sibilant_rules, ["ч"] = unstressed_sibilant_rules, ["ж"] = unstressed_sibilant_rules, ["ц"] = unstressed_c_rules, ["к"] = velar_rules, ["г"] = velar_rules, ["х"] = velar_rules, } export.nonsyllabic_suffixes = m_table.listToSet({"", "ъ", "ь", "й"}) export.sibilant_suffixes = m_table.listToSet({"ш", "щ", "ч", "ж"}) return export tfanhpvnmof7n8p3i23x8y7ww8143a1 5672504 5672503 2026-06-29T15:25:52Z MustafaCavlak 59368 5672504 Scribunto text/plain --[[ This module holds functions shared between ru-noun and ru-adjective. ]] local export = {} local lang = require("Modül:diller").getirKodaGore("ru") local m_links = require("Modül:bağlantılar") local m_table = require("Modül:table") local com = require("Modül:ru-genel") local m_ru_translit = require("Modül:ru-alfabeçeviri") local m_table_tools = require("Modül:table tools") local u = mw.ustring.char local rfind = mw.ustring.find local rsubn = mw.ustring.gsub local unpack = unpack or table.unpack -- Lua 5.2 compatibility local usub = mw.ustring.sub local HYPMARKER = "⟐" -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end -- Insert an entry into an existing list if not already present, comparing the entry to items in the existing list -- using a key function. If entry already found, combine it into the existing entry using combine_func, a function of -- two arguments (the existing and new entries), which should return the combined entry. Return false if entry already -- found, true if new entry inserted. If combine_func not specified, the existing entry is left alone. If combine_func -- is specified, the return value will be written over the existing value (i.e. the existing list will be modified -- in-place). -- -- FIXME: General enough to consider moving to [[Modül:table]]. local function insert_if_not_by_key(list, new_entry, keyfunc, combine_func) local new_entry_key = keyfunc(new_entry) for i, item in ipairs(list) do local item_key = keyfunc(item) if m_table.deepEquals(item_key, new_entry_key) then if combine_func then list[i] = combine_func(item, new_entry) end return false end end table.insert(list, new_entry) return true end -------------------------------------------------------------------------- -- Used for manual translit -- -------------------------------------------------------------------------- function export.combine_stem_and_suffix(stem, tr, suf, rules, old) local first = usub(suf, 1, 1) if rules then local conv = rules[first] if conv then local ending = usub(suf, 2) -- The following regexp is not quite the same as com.vowels. For one thing -- it includes й, which is important. It leaves out ы, which may or may not -- be important. if old and conv == "и" and rfind(ending, "^́?[аеёиійоуэюяѣ]") then conv = "і" end suf = conv .. ending end end -- If <adj> is present in the suffix, it means we need to translate it -- specially; do that now. local is_adj = rfind(suf, "<adj>") suf = rsub(suf, "<adj>", "") local suftr = is_adj and m_ru_translit.tr_adj(suf, "mono") return com.concat_russian_tr(stem, tr, suf, suftr, "dopair"), suf end -------------------------------------------------------------------------- -- Formatting forms for display -- -------------------------------------------------------------------------- -- Generate a string to substitute into a particular form in a Wiki-markup table. `forms` is the list of forms, -- generated by concat_word_forms(). `is_lemma` is true if we're formatting the entry for use in displaying the lemma -- in the declension table title. In this case, we don't include the translit, and remove monosyllabic accents from the -- Cyrillic (but not in multiword expressions). `accel_form` is the form code to speicfy in the accelerator, e.g. -- 'nom|m|s', or nil for no accelerator. `lemma_forms` is the list of {RU, TR} lemma forms for use in the accelerator, -- or nil if `accel_form` is nil. `remove_monosyllabic_accents_lemma_only` indicates that monosyllabic accents should -- be removed only in the lemma; otherwise we remove them from all forms. (FIXME: Rethink why we have this flag; we -- should be consistent.) function export.show_form(forms, is_lemma, accel_form, lemma_forms, remove_monosyllabic_accents_lemma_only) local russianvals = {} local latinvals = {} local lemmavals = {} -- First fetch the lemma forms and translit. If there are adjacent forms that have identical Russian including -- stress but different translit (e.g. азербайджа́нец with translits 'azerbajdžánec' and 'azɛrbajdžánec'), we -- combine the translits, comma-separating them. (This is necessary because there is currently only one tr= -- field per term.) We don't do this when processing the forms below; instead we handle this in a different -- and more general fashion (see below). local lemmaru, lemmatr if accel_form and lemma_forms and lemma_forms[1] ~= "-" then lemma_forms = com.combine_translit_of_duplicate_forms(com.strip_notes_from_forms(lemma_forms)) for i, form in ipairs(lemma_forms) do local ru, tr = unpack(lemma_forms[i]) ru, tr = com.remove_monosyllabic_accents(ru, tr) lemma_forms[i] = {ru, tr} end lemmaru, lemmatr = com.unzip_forms(lemma_forms) end -- Accumulate separately the Russian and transliteration into RUSSIANVALS and LATINVALS, then concatenate each down -- below. We need a fair amount of logic here: -- (1) to separate out footnote symbols; -- (2) to separate out the hypothetical marker (a footnote symbol but causes display of the Russian and translit -- in a special font); -- (3) to maybe remove monosyllabic accents; -- (4) to deduplicate repeated forms. -- We used to generate the display (HTML) as we went, but this prevented proper deduplication because the -- accelerator classes included in the HTML were different for otherwise identical forms. (Specifically, if two -- forms are the same in the Russian but different in the translit, the Russian will have different display forms -- because the translit is included in the accelerator classes.) So what we do is accumulate, separately for the -- Russian and translit, objects containing the entry (Russian or translit), the separated footnote symbols, -- whether the entry is hypothetical, and (for Russian only) the corresponding translit(s), for accelerator -- generation. As we accumulate, we duduplicate based only on comparing the entries of two objects. If we need to -- deduplicate two objects, we also need to combine their footnotes and transliteration (in the latter case, by -- comma-separating; we do this because there is only one tr= field for each term). for _, form in ipairs(forms) do local ru, tr = form[1], form[2] local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) trnotes = rsub(trnotes, HYPMARKER, "") end if (is_lemma or not remove_monosyllabic_accents_lemma_only) then ruentry, trentry = com.remove_monosyllabic_accents(ruentry, trentry) end local ishyp = rfind(runotes, HYPMARKER) if ishyp then runotes = rsub(runotes, HYPMARKER, "") end local ruobj = {entry = ruentry, tr = {trentry or true}, ishyp = ishyp, notes = runotes} if not trentry then trentry = com.translit_no_links(ruentry) end if not trnotes then trnotes = com.translit_no_links(runotes) end local trobj = {entry = trentry, ishyp = ishyp, notes = trnotes} local function keyfunc(obj) return obj.entry end local function combine_func_ru(obj1, obj2) for _, tr in ipairs(obj2.tr) do m_table.insertIfNot(obj1.tr, tr) end obj1.notes = obj1.notes .. obj2.notes obj1.ishyp = obj1.ishyp or obj2.ishyp return obj1 end local function combine_func_tr(obj1, obj2) obj1.notes = obj1.notes .. obj2.notes obj1.ishyp = obj1.ishyp or obj2.ishyp return obj1 end if is_lemma then -- m_table.insertIfNot(lemmavals, ruspan .. " (" .. trspan .. ")") insert_if_not_by_key(lemmavals, ruobj, keyfunc, combine_func_ru) else insert_if_not_by_key(russianvals, ruobj, keyfunc, combine_func_ru) insert_if_not_by_key(latinvals, trobj, keyfunc, combine_func_tr) end end -- Now finally format each object and concatenate them together. local function concatenate_ru(objs) local is_missing = false for i, obj in ipairs(objs) do local accel = nil if lemmaru then local translit = nil if #obj.tr == 1 and obj.tr[1] == true then -- no translit else for j, tr in ipairs(obj.tr) do if tr == true then obj.tr[j] = com.translit_no_links(obj.entry) end end translit = table.concat(obj.tr, ", ") end accel = {form = accel_form, translit = translit, lemma = lemmaru, lemma_translit = lemmatr} end if obj.entry == "-" and #forms == 1 then objs[i] = "&mdash;" is_missing = true end if obj.ishyp then -- no accelerator for hypothetical forms objs[i] = m_links.full_link({lang = lang, term = nil, alt = obj.entry, tr = "-"}, "hypothetical") else objs[i] = m_links.full_link({lang = lang, term = obj.entry, tr = "-", accel = accel}) end objs[i] = objs[i] .. m_table_tools.superscript_notes(obj.notes) end return table.concat(objs, ", "), is_missing end local function concatenate_tr(objs) local scriptutils = require("Modül:alfabe araçları") for i, obj in ipairs(objs) do local trspan = m_links.remove_links(obj.entry) .. m_table_tools.superscript_notes(obj.notes) if obj.ishyp then -- FIXME, in the old [[Modül:ru-ad]] code, notes were omitted from hypothetical entries. Correct? objs[i] = scriptutils.tag_text(trspan, lang, require("Modül:alfabeler").getirKodaGore("Latn"), "hypothetical") else objs[i] = scriptutils.tag_translit(trspan, lang, "default", " style=\"color: var(--wikt-palette-grey-8,#888);\"") end end return table.concat(objs, ", ") end if is_lemma then local russian_span, is_missing = concatenate_ru(lemmavals) return russian_span else local russian_span, is_missing = concatenate_ru(russianvals) if is_missing then return russian_span end local latin_span = concatenate_tr(latinvals) return russian_span .. "<br />" .. latin_span end end -------------------------------------------------------------------------- -- Sibilant/Velar/ц rules -- -------------------------------------------------------------------------- local stressed_sibilant_rules = { ["я"] = "а", ["ы"] = "и", ["ё"] = "о́", ["ю"] = "у", } local stressed_c_rules = { ["я"] = "а", ["ё"] = "о́", ["ю"] = "у", } local unstressed_sibilant_rules = { ["я"] = "а", ["ы"] = "и", ["о"] = "е", ["ю"] = "у", } local unstressed_c_rules = { ["я"] = "а", ["о"] = "е", ["ю"] = "у", } local velar_rules = { ["ы"] = "и", } export.stressed_rules = { ["ш"] = stressed_sibilant_rules, ["щ"] = stressed_sibilant_rules, ["ч"] = stressed_sibilant_rules, ["ж"] = stressed_sibilant_rules, ["ц"] = stressed_c_rules, ["к"] = velar_rules, ["г"] = velar_rules, ["х"] = velar_rules, } export.unstressed_rules = { ["ш"] = unstressed_sibilant_rules, ["щ"] = unstressed_sibilant_rules, ["ч"] = unstressed_sibilant_rules, ["ж"] = unstressed_sibilant_rules, ["ц"] = unstressed_c_rules, ["к"] = velar_rules, ["г"] = velar_rules, ["х"] = velar_rules, } export.nonsyllabic_suffixes = m_table.listToSet({"", "ъ", "ь", "й"}) export.sibilant_suffixes = m_table.listToSet({"ш", "щ", "ч", "ж"}) return export tdxva6w3kct9tttsryhs9o2avr02q8g Şablon:ru-eylem-2a-impf 10 1590996 5672485 2026-06-29T14:05:45Z MustafaCavlak 59368 Yeni sayfa : <div class="NavFrame" style="width:80%"> <div class="NavHead"style="background:#E0B0FF; text-align:left">''{{{1|{{SAYFAADI}}}}}'' eyleminin çekimi</small></div> <div class="NavContent"> {| class="wikitable inflection-table" |+ |- ! colspan="4" style="background:#E6E6FA; | tamamlanmamış bakış açısı |- ! colspan="2" style="background:#89CFF0; | mastar | colspan="2" | {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#E6E6FA; | eylemsiler ! style="background:#E6E6FA... 5672485 wikitext text/x-wiki <div class="NavFrame" style="width:80%"> <div class="NavHead"style="background:#E0B0FF; text-align:left">''{{{1|{{SAYFAADI}}}}}'' eyleminin çekimi</small></div> <div class="NavContent"> {| class="wikitable inflection-table" |+ |- ! colspan="4" style="background:#E6E6FA; | tamamlanmamış bakış açısı |- ! colspan="2" style="background:#89CFF0; | mastar | colspan="2" | {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#E6E6FA; | eylemsiler ! style="background:#E6E6FA; | şimdiki zaman ! style="background:#E6E6FA; | geçmiş zaman |- ! colspan="2" style="background:#89CFF0; | etken ortaç | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ющий}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́вший}} |- ! colspan="2" style="background:#89CFF0; | edilgen ortaç | {{#switch:{{{geçişsiz|}}}|1=—|#default={{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́емый}}}} | {{#switch:{{{ego|}}}|-=—|#default={{l-self|ru|{{{ego|{{#invoke:string|sub|s={{{1}}}|j=-6}}о́ванный}}}}}}} |- ! colspan="2" style="background:#89CFF0; | ulaç | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́я}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́в}},<br>{{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́вши}} |- ! colspan="2" style="background:#E6E6FA; | ! style="background:#E6E6FA; | şimdiki zaman ! style="background:#E6E6FA; | gelecek zaman |- ! colspan="2" style="background:#89CFF0; | 1. tekil şahıs (я) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ю}} | {{l-self|ru|бу́ду}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 2. tekil şahıs (ты) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ешь}} | {{l-self|ru|бу́дешь}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 3. tekil şahıs (он/она/оно) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ет}} | {{l-self|ru|бу́дет}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 1. çoğul şahıs (мы) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ем}} | {{l-self|ru|бу́дем}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 2. çoğul şahıs (вы) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ете}} | {{l-self|ru|бу́дете}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 3. çoğul şahıs (они) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ют}} | {{l-self|ru|бу́дут}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#E6E6FA; | emir kipi ! style="background:#E6E6FA; | tekil ! style="background:#E6E6FA; | çoğul |- ! colspan="2" style="background:#89CFF0; | 2. şahıs (ты/вы) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́й}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́йте}} |- ! colspan="2" style="background:#E6E6FA; | geçmiş zaman ! style="background:#E6E6FA; | tekil ! style="background:#E6E6FA; | çoğul (мы/вы/они́) |- ! colspan="2" style="background:#89CFF0; | eril (я/ты/он) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́л}} | |- ! colspan="2" style="background:#89CFF0; | dişil (я/ты/она́) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́ла}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́ли}} |- ! colspan="2" style="background:#89CFF0; | nötr (оно́) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́ло}} | |}</div></div><noinclude>{{belgeleme}}</noinclude> j0sc2jcha762ooe36j2fkbhop220szz 5672488 5672485 2026-06-29T14:27:48Z MustafaCavlak 59368 5672488 wikitext text/x-wiki <div class="NavFrame" style="width:80%"> <div class="NavHead"style="background:#E0B0FF; text-align:left">''{{{1|{{SAYFAADI}}}}}'' eyleminin çekimi</small></div> <div class="NavContent"> {| class="wikitable inflection-table" |+ |- ! colspan="4" style="background:#E6E6FA; | tamamlanmamış bakış açısı |- ! colspan="2" style="background:#89CFF0; | mastar | colspan="2" | {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#E6E6FA; | eylemsiler ! style="background:#E6E6FA; | şimdiki zaman ! style="background:#E6E6FA; | geçmiş zaman |- ! colspan="2" style="background:#89CFF0; | etken ortaç | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ющий}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́вший}} |- ! colspan="2" style="background:#89CFF0; | edilgen ortaç | {{#switch:{{{geçişsiz|}}}|1=—|#default={{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́емый}}}} | {{#switch:{{{ego|}}}|-=—|#default={{l-self|ru|{{{ego|{{#invoke:string|sub|s={{{1}}}|j=-7}}о́ванный}}}}}}} |- ! colspan="2" style="background:#89CFF0; | ulaç | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́я}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́в}},<br>{{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́вши}} |- ! colspan="2" style="background:#E6E6FA; | ! style="background:#E6E6FA; | şimdiki zaman ! style="background:#E6E6FA; | gelecek zaman |- ! colspan="2" style="background:#89CFF0; | 1. tekil şahıs (я) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ю}} | {{l-self|ru|бу́ду}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 2. tekil şahıs (ты) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ешь}} | {{l-self|ru|бу́дешь}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 3. tekil şahıs (он/она/оно) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ет}} | {{l-self|ru|бу́дет}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 1. çoğul şahıs (мы) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ем}} | {{l-self|ru|бу́дем}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 2. çoğul şahıs (вы) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ете}} | {{l-self|ru|бу́дете}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#89CFF0; | 3. çoğul şahıs (они) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ют}} | {{l-self|ru|бу́дут}} {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#E6E6FA; | emir kipi ! style="background:#E6E6FA; | tekil ! style="background:#E6E6FA; | çoğul |- ! colspan="2" style="background:#89CFF0; | 2. şahıs (ты/вы) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́й}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́йте}} |- ! colspan="2" style="background:#E6E6FA; | geçmiş zaman ! style="background:#E6E6FA; | tekil ! style="background:#E6E6FA; | çoğul (мы/вы/они́) |- ! colspan="2" style="background:#89CFF0; | eril (я/ты/он) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́л}} | |- ! colspan="2" style="background:#89CFF0; | dişil (я/ты/она́) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́ла}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́ли}} |- ! colspan="2" style="background:#89CFF0; | nötr (оно́) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́ло}} | |}</div></div><noinclude>{{belgeleme}}</noinclude> 6vvnosjxklbb8y547zytioeb641c6qd Şablon:ru-eylem-2a-pf 10 1590997 5672486 2026-06-29T14:18:57Z MustafaCavlak 59368 Yeni sayfa : <div class="NavFrame" style="width:80%"> <div class="NavHead"style="background:#E0B0FF; text-align:left">''{{{1|{{SAYFAADI}}}}}'' eyleminin çekimi</small></div> <div class="NavContent"> {| class="wikitable inflection-table" |+ |- ! colspan="4" style="background:#E6E6FA; | tamamlanmış bakış açısı |- ! colspan="2" style="background:#89CFF0; | mastar | colspan="2" | {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#E6E6FA; | eylemsiler ! style="background:#E6E6FA;... 5672486 wikitext text/x-wiki <div class="NavFrame" style="width:80%"> <div class="NavHead"style="background:#E0B0FF; text-align:left">''{{{1|{{SAYFAADI}}}}}'' eyleminin çekimi</small></div> <div class="NavContent"> {| class="wikitable inflection-table" |+ |- ! colspan="4" style="background:#E6E6FA; | tamamlanmış bakış açısı |- ! colspan="2" style="background:#89CFF0; | mastar | colspan="2" | {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#E6E6FA; | eylemsiler ! style="background:#E6E6FA; | şimdiki zaman ! style="background:#E6E6FA; | geçmiş zaman |- ! colspan="2" style="background:#89CFF0; | etken ortaç | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́вший}} |- ! colspan="2" style="background:#89CFF0; | edilgen ortaç | — | {{#switch:{{{ego|}}}|-=—|#default={{l-self|ru|{{{ego|{{#invoke:string|sub|s={{{1}}}|j=-6}}о́ванный}}}}}}} |- ! colspan="2" style="background:#89CFF0; | ulaç | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́в}},<br>{{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́вши}} |- ! colspan="2" style="background:#E6E6FA; | ! style="background:#E6E6FA; | şimdiki zaman ! style="background:#E6E6FA; | gelecek zaman |- ! colspan="2" style="background:#89CFF0; | 1. tekil şahıs (я) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ю}} |- ! colspan="2" style="background:#89CFF0; | 2. tekil şahıs (ты) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ешь}} |- ! colspan="2" style="background:#89CFF0; | 3. tekil şahıs (он/она/оно) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ет}} |- ! colspan="2" style="background:#89CFF0; | 1. çoğul şahıs (мы) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ем}} |- ! colspan="2" style="background:#89CFF0; | 2. çoğul şahıs (вы) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ете}} |- ! colspan="2" style="background:#89CFF0; | 3. çoğul şahıs (они) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́ют}} |- ! colspan="2" style="background:#E6E6FA; | emir kipi ! style="background:#E6E6FA; | tekil ! style="background:#E6E6FA; | çoğul |- ! colspan="2" style="background:#89CFF0; | 2. şahıs (ты/вы) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́й}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}у́йте}} |- ! colspan="2" style="background:#E6E6FA; | geçmiş zaman ! style="background:#E6E6FA; | tekil ! style="background:#E6E6FA; | çoğul (мы/вы/они́) |- ! colspan="2" style="background:#89CFF0; | eril (я/ты/он) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́л}} | |- ! colspan="2" style="background:#89CFF0; | dişil (я/ты/она́) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́ла}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́ли}} |- ! colspan="2" style="background:#89CFF0; | nötr (оно́) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-6}}ова́ло}} | |}</div></div><noinclude>{{belgeleme}}</noinclude> lmokdb644jtt8hur6a0a31vbhz4bie1 5672489 5672486 2026-06-29T14:29:17Z MustafaCavlak 59368 5672489 wikitext text/x-wiki <div class="NavFrame" style="width:80%"> <div class="NavHead"style="background:#E0B0FF; text-align:left">''{{{1|{{SAYFAADI}}}}}'' eyleminin çekimi</small></div> <div class="NavContent"> {| class="wikitable inflection-table" |+ |- ! colspan="4" style="background:#E6E6FA; | tamamlanmış bakış açısı |- ! colspan="2" style="background:#89CFF0; | mastar | colspan="2" | {{l-self|ru|{{{1}}}}} |- ! colspan="2" style="background:#E6E6FA; | eylemsiler ! style="background:#E6E6FA; | şimdiki zaman ! style="background:#E6E6FA; | geçmiş zaman |- ! colspan="2" style="background:#89CFF0; | etken ortaç | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́вший}} |- ! colspan="2" style="background:#89CFF0; | edilgen ortaç | — | {{#switch:{{{ego|}}}|-=—|#default={{l-self|ru|{{{ego|{{#invoke:string|sub|s={{{1}}}|j=-7}}о́ванный}}}}}}} |- ! colspan="2" style="background:#89CFF0; | ulaç | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́в}},<br>{{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́вши}} |- ! colspan="2" style="background:#E6E6FA; | ! style="background:#E6E6FA; | şimdiki zaman ! style="background:#E6E6FA; | gelecek zaman |- ! colspan="2" style="background:#89CFF0; | 1. tekil şahıs (я) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ю}} |- ! colspan="2" style="background:#89CFF0; | 2. tekil şahıs (ты) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ешь}} |- ! colspan="2" style="background:#89CFF0; | 3. tekil şahıs (он/она/оно) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ет}} |- ! colspan="2" style="background:#89CFF0; | 1. çoğul şahıs (мы) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ем}} |- ! colspan="2" style="background:#89CFF0; | 2. çoğul şahıs (вы) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ете}} |- ! colspan="2" style="background:#89CFF0; | 3. çoğul şahıs (они) | — | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́ют}} |- ! colspan="2" style="background:#E6E6FA; | emir kipi ! style="background:#E6E6FA; | tekil ! style="background:#E6E6FA; | çoğul |- ! colspan="2" style="background:#89CFF0; | 2. şahıs (ты/вы) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́й}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}у́йте}} |- ! colspan="2" style="background:#E6E6FA; | geçmiş zaman ! style="background:#E6E6FA; | tekil ! style="background:#E6E6FA; | çoğul (мы/вы/они́) |- ! colspan="2" style="background:#89CFF0; | eril (я/ты/он) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́л}} | |- ! colspan="2" style="background:#89CFF0; | dişil (я/ты/она́) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́ла}} | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́ли}} |- ! colspan="2" style="background:#89CFF0; | nötr (оно́) | {{l-self|ru|{{#invoke:string|sub|s={{{1}}}|j=-7}}ова́ло}} | |}</div></div><noinclude>{{belgeleme}}</noinclude> siq8u0anoq2qvgoa0u1wl698uygaixf рисовать 0 1590998 5672490 2026-06-29T14:29:48Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Köken=== {{nakledilen|ru|pl|rysować}}, {{kökenli|ru|gmh|rīʒen}}, {{kökenli|ru|goh|rīȥan}}, {{kökenli|ru|gmw-pro|*hrītan}}, {{kökenli|ru|gem-pro|*hrītaną}}. ===Söyleniş=== * {{IPA|dil=ru|[rʲɪsɐˈvatʲ]}} * {{ses|dil=ru|Ru-рисовать.ogg}} ===Eylem=== {{ru-eylem|рисова́ть|impf|pf=нарисова́ть}} # [[çizmek]] ====Çekimleme==== {{ru-eylem-2a-impf|рисова́ть}} 5672490 wikitext text/x-wiki ==Rusça== ===Köken=== {{nakledilen|ru|pl|rysować}}, {{kökenli|ru|gmh|rīʒen}}, {{kökenli|ru|goh|rīȥan}}, {{kökenli|ru|gmw-pro|*hrītan}}, {{kökenli|ru|gem-pro|*hrītaną}}. ===Söyleniş=== * {{IPA|dil=ru|[rʲɪsɐˈvatʲ]}} * {{ses|dil=ru|Ru-рисовать.ogg}} ===Eylem=== {{ru-eylem|рисова́ть|impf|pf=нарисова́ть}} # [[çizmek]] ====Çekimleme==== {{ru-eylem-2a-impf|рисова́ть}} dew3afts7ybd1izpgkefin44uzv6eb6 Kategori:Lehçeden nakledilen Rusça sözcükler 14 1590999 5672491 2026-06-29T14:30:33Z MustafaCavlak 59368 Yeni sayfa : {{kategori köken|dil=ru|köken=pl|tip=nakledilen}} 5672491 wikitext text/x-wiki {{kategori köken|dil=ru|köken=pl|tip=nakledilen}} c91wx3mik4jy2dy8lm1v7lvk990ce8f Kategori:Orta Yüksek Almanca kökenli Rusça sözcükler 14 1591000 5672492 2026-06-29T14:30:59Z MustafaCavlak 59368 Yeni sayfa : {{kategori köken|dil=ru|köken=gmh}} 5672492 wikitext text/x-wiki {{kategori köken|dil=ru|köken=gmh}} 71eay48bs3sftnk1fhheu6hsphs4e00 Kategori:Eski Yüksek Almanca kökenli Rusça sözcükler 14 1591001 5672493 2026-06-29T14:31:17Z MustafaCavlak 59368 Yeni sayfa : {{kategori köken|dil=ru|köken=goh}} 5672493 wikitext text/x-wiki {{kategori köken|dil=ru|köken=goh}} lrez55f603sifgh6jvn7yuqqo051m1g Kategori:Ana Batı Cermence kökenli Rusça sözcükler 14 1591002 5672494 2026-06-29T14:31:55Z MustafaCavlak 59368 Yeni sayfa : {{kategori köken|dil=ru|köken=gmw-pro}} 5672494 wikitext text/x-wiki {{kategori köken|dil=ru|köken=gmw-pro}} 0zez59kkjvxhf3722uyc8e0erucp7ih Kategori:Ana Cermence kökenli Rusça sözcükler 14 1591003 5672495 2026-06-29T14:32:11Z MustafaCavlak 59368 Yeni sayfa : {{kategori köken|dil=ru|köken=gem-pro}} 5672495 wikitext text/x-wiki {{kategori köken|dil=ru|köken=gem-pro}} 74bo3qfevd903d5n4duumaes8wcul6p нарисовать 0 1591004 5672496 2026-06-29T14:34:16Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Köken=== {{ön ek|dil=ru|на|рисова́ть}} ===Söyleniş=== * {{IPA|dil=ru|[nərʲɪsɐˈvatʲ]}} * {{ses|dil=ru|Ru-нарисовать.ogg}} ===Eylem=== {{ru-eylem|нарисова́ть|pf|impf=рисова́ть}} # [[çizmek]] ====Çekimleme==== {{ru-eylem-2a-pf|нарисова́ть}} 5672496 wikitext text/x-wiki ==Rusça== ===Köken=== {{ön ek|dil=ru|на|рисова́ть}} ===Söyleniş=== * {{IPA|dil=ru|[nərʲɪsɐˈvatʲ]}} * {{ses|dil=ru|Ru-нарисовать.ogg}} ===Eylem=== {{ru-eylem|нарисова́ть|pf|impf=рисова́ть}} # [[çizmek]] ====Çekimleme==== {{ru-eylem-2a-pf|нарисова́ть}} k1u5aciqoeq9iprf5q7qdzxtnlg2vq4 Kategori:Rusça на- ön ekiyle oluşmuş sözcükler 14 1591005 5672497 2026-06-29T14:35:00Z MustafaCavlak 59368 Yeni sayfa : {{kategori ek|ru|ön|на-}} 5672497 wikitext text/x-wiki {{kategori ek|ru|ön|на-}} ds90ti3sgrg8919yvm37cc5129ta2il Modül:ru-eylem 828 1591006 5672498 2026-06-29T15:01:53Z MustafaCavlak 59368 imported from en 5672498 Scribunto text/plain --[=[ This module contains functions for creating inflection tables for Russian verbs. Author: Benwing, rewritten from early version by Atitarev, earliest version by CodeCat NOTE: This module is partly converted to support manual translit, in the form CYRILLIC//LATIN (i.e. with a // separating the Cyrillic and Latin parts). All the general infrastructure supports manual translit; the only thing that doesn't is some of the specific verb conjugation functions. In particular, all of the class 1, 2, 3 and 4 conjugation functions support manual translit, and the rest don't. To convert another, follow the model of one of the already-converted functions. Note that an individual form (an entry in the 'forms' table) can be either a string (no special manual translit; generally this originates from the portion of the code that doesn't support manual translit), or a one-element list {CYRILLIC} (no special manual translit), or a two-element list {CYRILLIC, LATIN} with manual translit specified. The code is careful only to generate manual translit when it's needed, to avoid penalizing the majority of cases where manual transit isn't needed. ]=] local m_str_utils = require("Module:string utilities") local m_utilities = require("Module:utilities") local m_table = require("Module:table") local m_links = require("Module:links") local com = require("Module:ru-common") local m_debug = require("Module:debug") local m_table_tools = require("Module:table tools") -- If enabled, compare this module with new version of module to make -- sure all conjugations are the same. local test_new_ru_verb_module = false local export = {} -- Within this module, conjugations are the functions that do the actual -- conjugating by creating the forms of a basic verb. -- They are defined further down. local conjugations = {} local lang = require("Module:languages").getByCode("ru") local u = m_str_utils.char local rfind = m_str_utils.find local rsubn = m_str_utils.gsub local rmatch = m_str_utils.match local rsplit = m_str_utils.split local usub = m_str_utils.sub local AC = u(0x0301) -- acute = ́ local DIA = u(0x0308) -- diaeresis = ̈ local PSEUDOCONS = u(0xFFF2) -- pseudoconsonant placeholder, matching ru-common local IRREG = "△" -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end -- version of rsubn() that returns a 2nd argument boolean indicating whether -- a substitution was made. local function rsubb(term, foo, bar) local retval, nsubs = rsubn(term, foo, bar) return retval, nsubs > 0 end -- Fancy version of ine() (if-not-empty). Converts empty string to nil, -- but also strips leading/trailing space and then single or double quotes, -- to allow for embedded spaces. local function ine(arg) if not arg then return nil end arg = rsub(arg, "^%s*(.-)%s*$", "%1") if arg == "" then return nil end local inside_quotes = rmatch(arg, '^"(.*)"$') if inside_quotes then return inside_quotes end inside_quotes = rmatch(arg, "^'(.*)'$") if inside_quotes then return inside_quotes end return arg end local function is_vowel_stem(stem) return rfind(stem, "[" .. com.vowel .. AC .. DIA .. "]$") end -- Return the next number to use as an internal note symbol, starting at 1. -- We look at existing internal notes to see if the symbol is already used. local function next_note_symbol(data) local nextsym = 1 while true do local sym_already_seen = false for _, note in ipairs(data.internal_notes) do if rfind(note, "^" .. nextsym .. " ") then sym_already_seen = true break end end if sym_already_seen then nextsym = nextsym + 1 else break end end return nextsym end -- FIXME: Move to utils -- Iterate over a chain of parameters, FIRST then PREF2, PREF3, ..., -- inserting into LIST (newly created if omitted). Return LIST. local function get_arg_chain(args, first, pref, list) if not list then list = {} end local val = args[first] local i = 2 while val do table.insert(list, val) val = args[pref .. i] i = i + 1 end return list end -- FIXME: Move to utils -- Set a chain of parameters, FIRST then PREF2, PREF3, ..., from LIST. local function set_arg_chain(args, first, pref, list) local param = first local i = 2 for _, val in ipairs(list) do args[param] = val param = pref .. i i = i + 1 end end local function normalize_form(form) if type(form) == "table" and m_table.length(form) == 1 then return form[1] end return form end -- For a given form in a conjugation table, we allow either strings or -- two-element lists {RUSSIAN, TRANSLIT}, where TRANSLIT can be nil -- (equivalent to a one-element list). When comparing them, we have to take -- this into account. local function forms_equal(form1, form2) return m_table.deepEquals(normalize_form(form1), normalize_form(form2)) end local function contains_form(forms, form) for _, f in ipairs(forms) do if forms_equal(f, form) then return true end end return false end -- FIXME: Move to utils -- Append to the end of a chain of parameters, FIRST then PREF2, PREF3, ..., -- if the value isn't already present. local function append_to_arg_chain(args, first, pref, newval) local nextarg = first local i = 2 if newval == "" then error("Internal error: attempt to insert blank value into arg chain") end while true do if not args[nextarg] then break end if forms_equal(args[nextarg], newval) then return nil end nextarg = pref .. i i = i + 1 end args[nextarg] = newval return nextarg end local function get_true_arg(arg, not_off_by_1) -- We normally move all params down by one because the first param is the -- verb type; so reflect this correctly if the arg is numeric and -- not_off_by_1 isn't given return (not_off_by_1 or type(arg) ~= "number") and arg or arg + 1 end local function getarg(args, arg, default, paramdesc, not_off_by_1) paramdesc = paramdesc or "Parameter " .. get_true_arg(arg, not_off_by_1) default = default or "-" --PAGENAME = mw.loadData("Module:headword/data").pagename local NAMESPACE = mw.title.getCurrentTitle().nsText return args[arg] or (NAMESPACE == "Template" and default) or error(paramdesc .. " has not been provided") end local function check_stressed_arg(val, arg) -- don't consider suffixes if not rfind(val, "^%-") and not com.is_nonsyllabic(val) and not com.is_stressed(val) then error("Argument value " .. val .. " (parameter " .. get_true_arg(arg) .. ") must be stressed") end return val end local function get_stressed_arg(args, arg, default, paramdesc) local retval = getarg(args, arg, default, paramdesc) check_stressed_arg(retval, arg) return retval end local function get_opt_stressed_arg(args, arg) return args[arg] and get_stressed_arg(args, arg) or nil end local function check_unstressed_arg(val, arg) if com.is_stressed(val) then error("Argument value " .. val .. " (parameter " .. get_true_arg(arg) .. ") should not be stressed") end return val end local function get_unstressed_arg(args, arg, default, paramdesc) local retval = getarg(args, arg, default, paramdesc) check_unstressed_arg(retval, arg) return retval end local function get_opt_unstressed_arg(args, arg) return args[arg] and get_unstressed_arg(args, arg) or nil end local function no_stray_args(args, maxarg) for i=(maxarg + 1), 20 do if args[i] then error("Value for argument " .. get_true_arg(i) .. " not allowed (" .. args[i] .. " supplied)") end end end -- Extract a form spec (either a single string or a two-element table {RU, TR} -- into the component Russian and transliterated components. Normally, if -- an explicit manual translit wasn't given, the resulting translit will be -- nil; but if ALWAYS_TRANSLIT is given, it will be auto-transliterated from -- the Russian as needed. local function extract_russian_tr(form, always_translit) local ru, tr if type(form) == "table" then ru, tr = form[1], form[2] else ru = form end if not tr and always_translit then tr = ru and com.translit(ru) end return ru, tr end local function strip_arg_status_prefix(arg) if not arg then return arg, "" end local subbed arg, subbed = rsubb(arg, "^awkward%-", "") if subbed then return arg, "awkward-" end arg, subbed = rsubb(arg, "^none%-", "") if subbed then return arg, "none-" end return arg, "" end local function track(page) m_debug.track("ru-verb/" .. page) return true end -- Forward functions local present_e_a local present_e_b local present_e_c local present_je local present_i local make_reflexive local make_pre_reform local parse_and_stress_override local handle_forms_and_overrides local finish_generating_forms local make_table local all_verb_types = { "pf", "pf-intr", "pf-refl", "pf-impers", "pf-intr-impers", "pf-refl-impers", "impf", "impf-intr", "impf-refl", "impf-impers", "impf-intr-impers", "impf-refl-impers"} -- Examples of alternatives in use: -- past_m2: со́здал/созда́л, пе́редал/переда́л, о́тдал/отда́л, при́нялся/принялся́ -- past_m3: for verbs with three past masculine sg forms: за́нялся, заня́лся, занялс́я (заня́ться) -- past_n2: да́ло, дал́о; вз́яло, взяло́ -- past_pl2: разобрали́сь (разобрали́) -- past_m_short: short forms in 3a (исчез, сох, etc.) -- past_f_short: short forms in 3a (исчезла, сохла, etc.) -- past_n_short: short forms in 3a (исчезло, сохло, etc.) -- past_pl_short: short forms in 3a (исчезли, сохли, etc.) -- past_adv_parts: -- тереть: тере́вши, тёрши, short: тере́в -- умереть: умере́вши, у́мерши, short: умере́в -- pres_adv_part: сыпля, сыпя, лёжа (лежать) -- pres_2sg2: сыплешь, сыпешь -- pres_3sg2: сыплет, сыпет -- pres_1pl2: сыплем, сыпем -- pres_2pl2: сыплете, сыпете -- pres_3pl2: сыплют, сыпют -- futr_2sg2: насыплешь, насыпешь -- futr_3sg2: насыплет, насыпет -- futr_1pl2: насыплем, насыпем -- futr_2pl2: насыплете, насыпете -- futr_3pl2: насыплют, насыпют -- List of all main verb forms. Short forms (those ending in "_short") -- must be listed after the corresponding non-short forms. local all_main_verb_forms = { -- present tense "pres_1sg", "pres_2sg", "pres_3sg", "pres_1pl", "pres_2pl", "pres_3pl", -- future tense "futr_1sg", "futr_2sg", "futr_3sg", "futr_1pl", "futr_2pl", "futr_3pl", -- present-future tense. The conjugation functions generate the -- "present-future" tense instead of either the present or future tense, -- since the same forms are used in the present imperfect and future -- perfect. These forms are later copied into the present or future in -- finish_generating_forms(). "pres_futr_1sg", "pres_futr_2sg", "pres_futr_3sg", "pres_futr_1pl", "pres_futr_2pl", "pres_futr_3pl", -- imperative "impr_sg", "impr_pl", -- past "past_m", "past_f", "past_n", "past_pl", "past_m_short", "past_f_short", "past_n_short", "past_pl_short", -- active participles "pres_actv_part", "past_actv_part", -- passive participles "pres_pasv_part", "past_pasv_part", -- adverbial participles "pres_adv_part", "past_adv_part", "past_adv_part_short", -- infinitive "infinitive" } -- List of all verb forms. Each element is a list, where the first element -- is the "main" form and the remainder are alternatives. The following -- *MUST* hold: -- 1. Forms must be given in the order they will appear in the outputted -- table. -- 2. Short forms (those ending in "_short") must be listed after the -- corresponding non-short forms. -- 3. For each person, e.g. '2sg', there must be the same number of -- futr_PERSON, pres_PERSON and pres_futr_PERSON forms, and the alternative -- forms must be listed in the same order. -- -- FIXME!!! We should fix things so we no longer need to compute this table. local all_verb_forms = {} -- Compile all_verb_forms for _, mainform in ipairs(all_main_verb_forms) do local entry = {} table.insert(entry, mainform) for i=2,9 do table.insert(entry, mainform .. i) end table.insert(all_verb_forms, entry) end local prop_aliases = { pap="past_actv_part", paptail="past_actv_part_tail", paptailall="past_actv_part_tailall", ppp="past_pasv_part", ppptail="past_pasv_part_tail", ppptailall="past_pasv_part_tailall", prap="pres_actv_part", praptail="pres_actv_part_tail", praptailall="pres_actv_part_tailall", prpp="pres_pasv_part", prpptail="pres_pasv_part_tail", prpptailall="pres_pasv_part_tailall", padp="past_adv_part", padptail="past_adv_part_tail", padptailall="past_adv_part_tailall", padp_short="past_adv_part_short", padp_shorttail="past_adv_part_short_tail", padp_shorttailall="past_adv_part_short_tailall", pradp="pres_adv_part", pradptail="pres_adv_part_tail", pradptailall="pres_adv_part_tailall", } -- Table mapping "main" to the list of all forms in the series (e.g. -- past_m, past_m2, past_m3, etc.). If a main form (e.g. past_m) is missing, -- it needs to end up with a value of "", whereas the alternatives -- (e.g. past_m2, past_m3) need to end up with a value of nil. local main_to_all_verb_forms = {} -- List of the main verb forms for the past. local past_verb_forms = {"past_m", "past_f", "past_n", "past_pl"} -- List of the main verb forms for the present. local pres_verb_forms = {"pres_1sg", "pres_2sg", "pres_3sg", "pres_1pl", "pres_2pl", "pres_3pl"} -- List of the main verb forms for the future. local futr_verb_forms = {"futr_1sg", "futr_2sg", "futr_3sg", "futr_1pl", "futr_2pl", "futr_3pl"} -- List of the main verb forms for the imperative. local impr_verb_forms = {"impr_sg", "impr_pl"} -- List of the main verb forms for participles. local part_verb_forms = {"pres_actv_part", "past_actv_part", "pres_pasv_part", "past_pasv_part", "pres_adv_part", "past_adv_part", "past_adv_part_short"} -- List of the main verb forms for present participles. local pres_part_verb_forms = {"pres_actv_part", "pres_pasv_part", "pres_adv_part"} -- List of the main verb forms for past participles. local past_part_verb_forms = {"past_actv_part", "past_pasv_part", "past_adv_part", "past_adv_part_short"} -- Compile main_to_all_verb_forms. for _, proplist in ipairs(all_verb_forms) do main_to_all_verb_forms[proplist[1]] = proplist end -- Map listing the forms to be displayed, and the verb forms used to generate -- the displayed form, in order. For example, under past_m will be found -- {"past_m_short", "past_m", "past_m2", "past_m3"} because those forms in -- that order are displayed in the table under "masculine singular past". local disp_verb_form_map = {} for _, proplist in ipairs(all_verb_forms) do local key = proplist[1] -- if we find short forms, insert them at the beginning of the list for -- the corresponding full forms. This requires that short forms are -- listed in all_verb_forms after the corresponding full forms. if rfind(key, "_short$") then local full_key = rsub(key, "_short$", "") -- short forms should occur in list after full forms assert(#(disp_verb_form_map[full_key]) > 0) -- build entry for full form, consisting first of the short forms, -- in order, then the full forms, in order. local new_entry = {} for _, form in ipairs(proplist) do table.insert(new_entry, form) end for _, form in ipairs(disp_verb_form_map[full_key]) do table.insert(new_entry, form) end disp_verb_form_map[full_key] = new_entry elseif rfind(key, "^pres_futr") then -- skip these forms, not displayed else disp_verb_form_map[key] = mw.clone(proplist) end end local all_verb_props = mw.clone(all_verb_forms) local non_form_props = {"title", "perf", "intr", "impers", "categories", "notes", "internal_notes"} for _, prop in ipairs(non_form_props) do table.insert(all_verb_props, {prop}) end -- Clone parent's args while also assigning nil to empty strings and splitting -- arg sets (numeric args separated by "or"), assigning named args to -- all all sets. Handle aliases in the process. Extract conjugation type -- from the first arg of the arg set (for the initial arg set, this will be -- arg 2 because arg 1 is the verb type), assigning to '.conj_type' of the -- arg set. Return arg sets. local function split_args_handle_aliases(frame) local args = frame:getParent().args local arg_sets = {} local arg_set = {} -- Verb type, e.g. impf, pf, impf-intr, pf-intr, impf-refl, pf-refl, etc. -- Default to impf on the template page so that there is no script error. local verb_type = getarg(args, 1, "impf", "Verb type (first parameter)") local offset = 1 -- Find maximum-numbered arg, allowing for holes. local max_arg = 1 -- needs to be 1 not 0 so template pages display ok for pname in pairs(args) do if type(pname) == "number" and pname > max_arg then max_arg = pname end end -- Now gather the numbered arguments. for i=2,(max_arg + 1) do local end_arg_set = false if i == max_arg + 1 or args[i] == "or" then end_arg_set = true end if end_arg_set then table.insert(arg_sets, arg_set) arg_set = {} offset = i else arg_set[i - offset] = ine(args[i]) end end -- Insert named arguments into all arg sets, mapping aliases appropriately. for pname, param in pairs(args) do if type(pname) == "string" then local argval = ine(param) local mainprop, num = rmatch(pname, "^([a-z_]+)([0-9]*)$") for i=1,#arg_sets do if not mainprop then arg_sets[i][pname] = argval else mainprop = prop_aliases[mainprop] or mainprop arg_sets[i][mainprop .. num] = argval end end end end -- If we're conjugating a suffix, insert a pseudoconsonant at the beginning -- of all forms, so they get conjugated as if ending in a consonant. -- We remove the pseudoconsonant later. for i=1,#arg_sets do local asif_prefix = (arg_sets[i]["asif_prefix"] or arg_sets[i][2] and rfind(arg_sets[i][2], "^%-") and PSEUDOCONS) if asif_prefix then for k, v in pairs(arg_sets[i]) do arg_sets[i][k] = rsub(v, "^%-", "-" .. asif_prefix) end end end -- Frob conjugation type. for i=1,#arg_sets do local arg1 = arg_sets[i][1] local conj_type if arg1 then local orig_arg1 = arg1 -- This complex spec matches matches 3°a, 3oa, 4a1a, 6c1a, -- 1a6a, 6a1as13, 6a1as14, 11*b, etc. conj_type = rmatch(arg1, "^([0-9]+[*°o0-9abc]*[abc]s?1?[34]?)") arg1 = rsub(arg1, "^[0-9]+[*°o0-9abc]*[abc]s?1?[34]?", "") if not conj_type then if rfind(arg1, "^irreg") then conj_type = "irreg" arg1 = rsub(arg1, "^irreg", "") end if not conj_type then -- Check for Cyrillic, a common mistake (esp. Cyrillic а) if rfind(orig_arg1, "[абцдеѣфгчийклмнопярстувшхызёюжэщьъ]") then error("Unrecognized conjugation type (WARNING, has Cyrillic in it): " .. orig_arg1) else error("Unrecognized conjugation type: " .. orig_arg1) end end end -- The * variant is conventionally written e.g. 11*b; if found in -- the conj_type, move it to the beginning of the remainder if rfind(conj_type, "%*") then conj_type = rsub(conj_type, "%*", "") arg1 = "*" .. arg1 end arg_sets[i][1] = arg1 else local NAMESPACE = mw.title.getCurrentTitle().nsText if NAMESPACE == "Template" and i == 1 then conj_type = "1a" else error("Must specify argument 2 (conjugation type)") end end arg_sets[i]["conj_type"] = conj_type end return arg_sets, verb_type end function export.do_generate_forms(arg_sets, verb_type, old) local set1 = arg_sets[1] local notes = get_arg_chain(set1, "notes", "notes") local forms = {} local categories = {} if not m_table.contains(all_verb_types, verb_type) then error("Invalid verb type " .. verb_type) end local data = {} data.verb_type = verb_type --impersonal data.impers = rfind(verb_type, "impers") data.intr = rfind(verb_type, "intr") data.perf = rfind(verb_type, "^pf") data.iter = set1["iter"] data.nopres = set1["nopres"] data.nopast = set1["nopast"] data.nofutr = set1["nofutr"] data.noimpr = set1["noimpr"] if data.iter and data.perf then error("Iterative verbs must be imperfective") end data.old = old data.has_ppp = set1["has_ppp"] data.has_prpp = set1["has_prpp"] data.ppp_override = false data.prpp_override = false for _, form in ipairs(main_to_all_verb_forms["past_pasv_part"]) do if set1[form] then data.ppp_override = true break end end data.main_ppp_override = not not set1["past_pasv_part"] for _, form in ipairs(main_to_all_verb_forms["pres_pasv_part"]) do if set1[form] then data.prpp_override = true break end end data.internal_notes = {} local titles = {} for i=1,#arg_sets do local args = arg_sets[i] local conj_type = args.conj_type -- Support e.g. 3oa in place of 3°a conj_type = rsub(conj_type, "o", "°") track("conj-" .. conj_type) -- FIXME, convert to regular category track("conj-" .. conj_type .. "/" .. verb_type) -- FIXME, convert to regular category data.conj_type = conj_type data.cat_conj_types = {conj_type} if conj_type == "irreg" then data.title = "irregular" else data.title = conj_type end if not conjugations[conj_type] then error("Unknown conjugation type '" .. conj_type .. "'") end if args[2] then local inf, tr = com.split_russian_tr(args[2]) if rfind(inf, "[тч]ься$") then inf = rsub(inf, "ся$", "") tr = com.strip_tr_ending(tr, "ся") data.refl = true elseif rfind(inf, "ти́?сь$") then -- 7a (вы́вестись), 7b (вести́сь) or derivative of -йти́ (разойти́сь) inf = rsub(inf, "сь$", "") tr = com.strip_tr_ending(tr, "сь") data.refl = true elseif rfind(inf, "[тч]ь$") then -- Allow monosyllabic infinitives to be specified without stress if com.is_monosyllabic(inf) and not rfind(inf, "^%-") then inf, tr = com.make_ending_stressed(inf, tr) end end if tr then args[2] = inf .. "//" .. tr else args[2] = inf end end if data.refl and data.intr then error("Can't specify -intr with reflexive verbs") end if data.has_ppp or data.has_prpp then if data.refl then error("Can't specify has_ppp=y or has_prpp=y with reflexive verbs") end if not data.intr then error("Can only specify has_ppp=y or has_prpp=y with intransitive verbs") end end data.shouldnt_have_ppp = data.refl or not data.has_ppp and data.intr data.shouldnt_have_prpp = data.refl or not data.has_prpp and data.intr if data.ppp_override and data.shouldnt_have_ppp then error("Shouldn't specify past passive participle with reflexive or intransitive verbs, if it's needed use has_ppp=y") elseif data.perf and not data.shouldnt_have_ppp and not data.ppp_override then -- possible omissions track("perfective-no-ppp") end if data.prpp_override and data.shouldnt_have_prpp then error("Shouldn't specify present passive participle with reflexive or intransitive verbs, if it's needed use has_prpp=y") end -- Call conjugation function. It will return a table of forms -- as if it's the first arg set. If it is in fact the first -- arg set, we just use the table directly (we may destructively -- modify it if there are later arg sets, but this is OK because -- no one else but us uses the table). Otherwise we need to -- append the values from the table to those of the previous -- arg sets. local arg_set_forms = conjugations[conj_type](args, data) if i == 1 then forms = arg_set_forms else for _, all_forms in pairs(main_to_all_verb_forms) do for _, form in ipairs(all_forms) do if arg_set_forms[form] then append_to_arg_chain(forms, all_forms[1], all_forms[1], arg_set_forms[form]) end end end end m_table.insertIfNot(titles, data.title) if conj_type == "irreg" then table.insert(categories, "Russian irregular verbs") end -- For irregular verbs, if the verb didn't set a specific cat_conj_type, -- it will be the same as the conj_type and be "irreg". In that case, -- replace it with the title, which might be a proper conjugation type -- like 4a or 8c/b (and remove anything starting with a slash, to -- account for cases like 8c/b). After doing this, the cat_conj_type -- might still begin with "irreg" (for sufficiently irregular verbs that -- they can't be assigned to any of the normal classes), in which case -- we don't create a class for the verb beyond "Russian irregular verbs" -- (set above). if data.cat_conj_types[1] == "irreg" then data.cat_conj_types = {rsub(rsub(data.title, "/.*", ""), "[*⑨]", "")} end for _, cat_conj_type in ipairs(data.cat_conj_types) do if not rmatch(cat_conj_type, "^irreg") then local class_num = rmatch(cat_conj_type, "^([0-9]+)") assert(class_num and class_num ~= "") table.insert(categories, "Russian class " .. class_num .. " verbs") table.insert(categories, "Russian class " .. cat_conj_type .. " verbs") end end end data.title = "class " .. table.concat(titles, " // ") .. (data.perf and " perfective" or " imperfective") .. (data.refl and " reflexive" or data.intr and " intransitive" or " transitive") .. (data.impers and " impersonal" or "") .. (data.iter and " iterative" or "") -- Perfective/imperfective if data.perf then table.insert(categories, "Russian perfective verbs") else table.insert(categories, "Russian imperfective verbs") end handle_forms_and_overrides(set1, forms, data) local function remove_pseudo(str) local toremove = set1["asif_prefix"] or PSEUDOCONS if str == nil then return str end str = rsub(str, "^%-" .. toremove, "-") -- also handle prefix after space, e.g. in futures str = rsub(str, " %-" .. toremove, " -") return str end -- Remove pseudoconsonant we may have inserted; if no ending, insert -- "(no suffix)". for k in pairs(forms) do if forms[k] == "-" .. PSEUDOCONS or type(forms[k] == "table") and forms[k][1] == "-" .. PSEUDOCONS then -- Make the translit empty. forms[k] = {"(no suffix)", ""} else if type(forms[k]) == "table" then forms[k][1] = remove_pseudo(forms[k][1]) forms[k][2] = remove_pseudo(forms[k][2]) else forms[k] = remove_pseudo(forms[k]) end end end -- Catch errors in verb arguments that lead to the infinitive not matching -- page title, but only in the main namespace. local NAMESPACE = mw.title.getCurrentTitle().nsText if NAMESPACE == "" then local PAGENAME = mw.loadData("Module:headword/data").pagename for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local inf = extract_russian_tr(forms[form]) if inf then inf, _ = m_table_tools.separate_notes(inf) -- remove any footnote symbols (e.g. грясти́) local inf_noaccent = com.remove_accents(inf) if inf ~= "-" then if data.refl then if rfind(inf_noaccent, "и$") then inf_noaccent = inf_noaccent .. "сь" inf = inf .. "сь" else inf_noaccent = inf_noaccent .. "ся" inf = inf .. "ся" end end if inf_noaccent ~= PAGENAME then error("Infinitive " .. inf .. " doesn't match pagename " .. PAGENAME) end end end end end -- Reflexive/intransitive/transitive if set1["reflex_stress"] then track("reflex-stress") end if data.refl then local reflex_stress = set1["reflex_stress"] or data.default_reflex_stress -- "ся́" make_reflexive(forms, reflex_stress and reflex_stress ~= "n" and reflex_stress ~= "no") table.insert(categories, "Russian reflexive verbs") elseif data.intr then table.insert(categories, "Russian intransitive verbs") else table.insert(categories, "Russian transitive verbs") end -- Impersonal if data.impers then table.insert(categories, "Russian impersonal verbs") end -- Iterative if data.iter then table.insert(categories, "Russian iterative verbs") end if data.old then make_pre_reform(forms) end finish_generating_forms(forms, data) return forms, data.title, data.perf, data.intr or data.refl, data.impers, categories, notes, data.internal_notes end local function fetch_forms(forms) local function fetch_one_form(form) local val = forms[form] local ru, tr if type(val) == "table" then ru, tr = val[1], val[2] elseif type(val) == "string" and val ~= "" and val ~= "-" then ru = val end if not ru then return nil end local ruentry = m_table_tools.get_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.get_notes(tr) end -- There shouldn't be any links. -- ruentry = m_links.remove_links(ruentry) -- There shouldn't be any vertical bars. -- ruentry = rsub(ruentry, "|", "<!>") -- if trentry then -- trentry = rsub(trentry, "|", "<!>") -- end return trentry and ruentry .. "//" .. trentry or ruentry end local vals = {} for _, proplist in ipairs(all_verb_forms) do local vallist = {} local propname = proplist[1] if not rfind(propname, "^pres_futr") then for _, prop in ipairs(proplist) do local val = fetch_one_form(prop) if val then table.insert(vallist, val) end end if #vallist > 0 then table.insert(vals, propname .. "=" .. table.concat(vallist, ",")) end end end return table.concat(vals, "|") end function export.generate_forms(frame) local arg_sets, verb_type = split_args_handle_aliases(frame) local old = frame.args["old"] or arg_sets[1]["old"] local forms = export.do_generate_forms(arg_sets, verb_type, old) return fetch_forms(forms) end -- The main entry point. -- This is the only function that can be invoked from a template. function export.show(frame) local arg_sets, verb_type = split_args_handle_aliases(frame) local old = frame.args["old"] or arg_sets[1]["old"] local arg_sets_clone if test_new_ru_verb_module then -- arg_sets may be modified by do_generate_forms() arg_sets_clone = mw.clone(arg_sets) end local forms, title, perf, intr, impers, categories, notes, internal_notes = export.do_generate_forms(arg_sets, verb_type, old) -- Test code to compare existing module to new one. if test_new_ru_verb_module then local m_new_ru_verb = require("Module:User:Benwing2/ru-verb") local newforms, newtitle, newperf, newintr, newimpers, newcategories, newnotes, newinternal_notes = m_new_ru_verb.do_generate_forms(arg_sets_clone, verb_type, old) local vals = mw.clone(forms) vals.title = title vals.perf = perf vals.intr = intr vals.impers = impers vals.categories = categories vals.notes = notes vals.internal_notes = internal_notes local newvals = mw.clone(newforms) newvals.title = newtitle newvals.perf = newperf newvals.intr = newintr newvals.impers = newimpers newvals.categories = newcategories newvals.notes = newnotes newvals.internal_notes = newinternal_notes local difconj = false for _, proplist in ipairs(all_verb_props) do for _, prop in ipairs(proplist) do local val = vals[prop] local newval = newvals[prop] -- deal with impedance mismatch between old style (plain string) -- and new style (Russian/translit array), and empty string vs. nil if not m_table.contains(non_form_props, prop) then if type(val) == "string" then val = {val} end if val and val[1] == "" then val = nil end if type(newval) == "string" then newval = {newval} end if newval and newval[1] == "" then newval = nil end end -- Ignore changes in pres_futr_*, which aren't displayed if not forms_equal(val, newval) and not rfind(prop, "^pres_futr") then -- Uncomment this to display the particular case and -- differing forms. --error(prop .. " " .. (val and concat_vals(val) or "nil") .. " || " .. (newval and concat_vals(newval) or "nil")) difconj = true break end end end track(difconj and "different-conj" or "same-conj") end return make_table(forms, title, perf, intr, impers, notes, internal_notes, old) .. m_utilities.format_categories(categories, lang) end --[=[ Functions for working with stems, paradigms, Russian/translit ]=] -- Combine a stem with optional translit with an ending and possibly a foonote -- symbol (which may be a tuple {RUNOTES, TRNOTES}), returning a tuple -- {RUSSIAN, TR}. local function combine(stem, tr, ending, note) if not ending or ending == "-" then return nil end local arg_status ending, arg_status = strip_arg_status_prefix(ending) if stem ~= "" and com.is_stressed(ending) then stem, tr = com.make_unstressed_once(stem, tr) end stem = arg_status .. stem if not note then return com.concat_russian_tr(stem, tr, ending, nil, "dopair") else local runotes, trnotes = extract_russian_tr(note) local ruending, trending = com.concat_russian_tr(ending, nil, runotes, trnotes) return com.concat_russian_tr(stem, tr, ruending, trending, "dopair") end end -- Set an individual form PARAM in FORMS with value based on stem STEM (with -- optional translit TR), ENDINGS (either a single string or a list of strings) -- and NOTE (nil, a string, or a tuple {RUSSIAN, TR}). If there are multiple -- endings listed, they will go successively into PARAM, PARAM2, etc. -- (e.g. past_m, past_m2, etc.). local function set_form(forms, param, stem, tr, endings, note) if type(endings) ~= "table" then endings = {endings} end local entries = {} for _, val in ipairs(endings) do m_table.insertIfNot(entries, combine(stem, tr, val, note)) end set_arg_chain(forms, param, param, entries) end -- Append to an individual form PARAM in FORMS with value based on stem STEM -- (with optional translit TR), ENDINGS (either a single string or a list of -- strings) and NOTE (nil, a string, or a tuple {RUSSIAN, TR}). If there are -- multiple endings listed, they will go successively into PARAM, PARAM2, etc. -- (e.g. past_m, past_m2, etc.), provided there are no existing forms already -- present. Duplicate forms aren't inserted. local function append_form(forms, param, stem, tr, endings, note) if type(endings) ~= "table" then endings = {endings} end for _, val in ipairs(endings) do append_to_arg_chain(forms, param, param, combine(stem, tr, val, note)) end end local function append_pres_futr(forms, stem, tr, sg1, sg2, sg3, pl1, pl2, pl3, note) append_form(forms, "pres_futr_1sg", stem, tr, sg1, note) append_form(forms, "pres_futr_2sg", stem, tr, sg2, note) append_form(forms, "pres_futr_3sg", stem, tr, sg3, note) append_form(forms, "pres_futr_1pl", stem, tr, pl1, note) append_form(forms, "pres_futr_2pl", stem, tr, pl2, note) append_form(forms, "pres_futr_3pl", stem, tr, pl3, note) end local function append_participles_2stem(forms, pres_stem, pres_tr, past_stem, past_tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, pres_note, past_note) append_form(forms, "pres_actv_part", pres_stem, pres_tr, pres_actv, pres_note) append_form(forms, "pres_pasv_part", pres_stem, pres_tr, pres_pasv, pres_note) append_form(forms, "pres_adv_part", pres_stem, pres_tr, pres_adv, pres_note) append_form(forms, "past_actv_part", past_stem, past_tr, past_actv, past_note) append_form(forms, "past_adv_part", past_stem, past_tr, past_adv, past_note) append_form(forms, "past_adv_part_short", past_stem, past_tr, past_adv_short, past_note) end local function append_participles(forms, stem, tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, note) append_participles_2stem(forms, stem, tr, stem, tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, note, note) end local function set_ppp(forms, stem, tr, ending, note) set_form(forms, "past_pasv_part", stem, tr, ending, note) end local function append_ppp(forms, stem, tr, ending, note) append_form(forms, "past_pasv_part", stem, tr, ending, note) end local function append_imper(forms, stem, tr, sg, pl, note) append_form(forms, "impr_sg", stem, tr, sg, note) append_form(forms, "impr_pl", stem, tr, pl, note) end local function set_past(forms, stem, tr, m, f, n, pl, note) set_form(forms, "past_m", stem, tr, m, note) set_form(forms, "past_f", stem, tr, f, note) set_form(forms, "past_n", stem, tr, n, note) set_form(forms, "past_pl", stem, tr, pl, note) end local function append_past(forms, stem, tr, m, f, n, pl, note) append_form(forms, "past_m", stem, tr, m, note) append_form(forms, "past_f", stem, tr, f, note) append_form(forms, "past_n", stem, tr, n, note) append_form(forms, "past_pl", stem, tr, pl, note) end -- Prepend a possibly-stressed prefix to all forms; if prefix is stressed, -- destress the forms before prepending. FIXME: Should support explicit -- manual translit. local function prepend_prefix(forms, prefix, pre_two_cons_prefix) pre_two_cons_prefix = pre_two_cons_prefix or prefix local stressed_prefix = com.is_stressed(prefix) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) if tr then error("Explicit manual translit not yet supported") end -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then if stressed_prefix then ru = com.make_unstressed(ru) end if rfind(ru, "^[" .. com.cons .. "][" .. com.cons .. "]") then forms[key] = pre_two_cons_prefix .. ru else forms[key] = prefix .. ru end end end end -- Apply regex substitution FROM -> TO to all forms. FIXME: Should support -- explicit manual translit. local function rsub_forms(forms, from, to) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) if tr then error("Explicit manual translit not yet supported") end -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then forms[key] = rsub(ru, from, to) end end end local variant_to_title = { ["[(2)]"] = "[②]", ["(2)"] = "②", ["[(3)]"] = "[③]", ["(3)"] = "③", ["[(4)]"] = "[④]", ["(4)"] = "④", ["[(5)]"] = "[⑤]", ["(5)"] = "⑤", ["[(6)]"] = "[⑥]", ["(6)"] = "⑥", ["[(7)]"] = "[⑦]", ["(7)"] = "⑦", ["[(8)]"] = "[⑧]", ["(8)"] = "⑧", ["(9)"] = "⑨", ["щ"] = "(-щ-)", ["ё"] = "(-ё-)", ["о"] = "(-о-)", ["жд"] = "(-жд-)", } local function prepare_past_stress_indicator(past_stress) if not past_stress or past_stress == "a" then return "" end past_stress = rsub(past_stress, "%(1%)", "①") past_stress = rsub(past_stress, "(.),%1①", "%1[①]") past_stress = rsub(past_stress, "(.)①,%1", "%1[①]") past_stress = rsub(past_stress, "''", "&#39;&#39;") past_stress = rsub(past_stress, "-nd", "") past_stress = rsub(past_stress, "-bd", "") return "/" .. past_stress end local function parse_variants(data, variants, allowed) -- Need to set these to nil in case of multiple arg sets data.imper_variant = nil data.var4 = nil data.var5 = nil data.var6 = nil data.ppp = nil data.var9 = nil data.shch = nil data.yo = nil data.o = nil data.zhd = nil data.star = nil variants = variants or "" local variant_title = "" if variants ~= "" then -- short-circuit the most common case -- Only recognize * variant for long-variant prefix at the beginning -- of the variant code block (where it gets moved if it's in the -- middle of the conjugation type, as it normally is) because a * -- also occurs in b*, a past stress variant code. if rfind(variants, "^%*") then -- Specify that the present/future tense has extra -о in the prefix: -- types 9*b (e.g. растере́ть, futr_1sg разотру́) and 11*b (e.g. изли́ть, -- futr_1sg изолью́). It can also occur with type 7*b (in -че́сть, -- e.g. счесть, сочту́; расче́сть, разочту́) and type 8*b (in -же́чь, e.g. -- сжечь, сожгу́) but these are always irregular and require the -- present tense to be specified explicitly. It can also occur -- with type 14*b (e.g. размя́ть, разомну́; сжать, сожну́; подожа́ть, подожму́), -- but for these verbs the present tense is unpredictable and -- must be specified explicitly. -- -- This can also occur where the extra -о occurs in the infinitive -- and past, but not the present tense: type 5*c (in -гна́ть, e.g. -- согна́ть, сгоню́; разогна́ться, разгоню́сь), type 6*c (in -стла́ть, e.g. -- подостла́ть, подстелю́; разостла́ть, расстелю́), type 6°*c -- (in -зва́ть, -бра́ть, -дра́ть, e.g. подозва́ть, подзову́; разобра́ться, разберу́сь); -- but these are always irregular and require the present tense -- to be specified explicitly. if not m_table.contains(allowed, "*") then error("Variant " .. var .. " not allowed for this verb class") end data.star = true variants = rsub(variants, "^*", "") end -- Allow brackets around both 5 and 6, e.g. [(5)(6)] variants = rsub(variants, "%[(%([56]%))(%([56]%))%]", "[%1][%2]") -- Handle all remaining variants. We do this using an rsub() function, -- where we pull out, parse and remove each variant in turn. variants = rsub(variants, "(%[?%(?[23456789ёощийьж+][дp]?%)?%]?)", function(var) if m_table.contains({"(2)", "[(2)]", "(3)", "[(3)]", "и", "й", "ь"}, var) then if data.imper_variant then error("Saw two imperative variants " .. data.imper_variant .. " and " .. var) end local is_23 = m_table.contains({"(2)", "[(2)]", "(3)", "[(3)]"}, var) if is_23 and not m_table.contains(allowed, "23") or not is_23 and not m_table.contains(allowed, "и") then error("Variant " .. var .. " not allowed for this verb class") end data.imper_variant = var elseif m_table.contains({"(4)", "[(4)]"}, var) then if data.var4 then error("Saw two variant-4 specs " .. data.var4 .. " and " .. var) end if not m_table.contains(allowed, "4") then error("Variant " .. var .. " not allowed for this verb class") end data.var4 = var == "(4)" and "req" or "opt" elseif m_table.contains({"(5)", "[(5)]"}, var) then if data.var5 then error("Saw two variant-5 specs " .. data.var5 .. " and " .. var) end if not m_table.contains(allowed, "5") then error("Variant " .. var .. " not allowed for this verb class") end data.var5 = var == "(5)" and "req" or "opt" elseif m_table.contains({"(6)", "[(6)]"}, var) then if data.var6 then error("Saw two variant-6 specs " .. data.var6 .. " and " .. var) end if not m_table.contains(allowed, "6") then error("Variant " .. var .. " not allowed for this verb class") end data.var6 = var == "(6)" and "req" or "opt" elseif m_table.contains({"(7)", "[(7)]", "(8)", "[(8)]", "+p"}, var) then if data.shouldnt_have_ppp then error("Shouldn't specify past passive participle with reflexive or intransitive verbs, if it's needed use has_ppp=y") end if data.ppp then error("Saw two past passive participle specs " .. data.ppp .. " and " .. var) end if m_table.contains({"(7)", "[(7)]"}, var) and not m_table.contains(allowed, "7") or m_table.contains({"(8)", "[(8)]"}, var) and not m_table.contains(allowed, "8") or var == "+p" and not m_table.contains(allowed, "+p") then error("Variant " .. var .. " not allowed for this verb class") end data.ppp = var elseif var == "(9)" then if data.var9 then error("Saw (9) twice") end if not m_table.contains(allowed, "9") then error("Variant " .. var .. " not allowed for this verb class") end data.var9 = true elseif var == "щ" then -- specify that the 1sg pres/futr and past passive participle -- of class 4/5/6 verbs iotate -т to -щ instead of -ч; cf. -- похи́тить (похи́щу) (4a), защити́ть (защищу́) (4b), -- поглоти́ть (поглощу́) (4c), клевета́ть (клевещу́) (6c) if data.shch then error("Saw щ twice") end if not m_table.contains(allowed, "щ") then error("Variant " .. var .. " not allowed for this verb class") end data.shch = "щ" elseif var == "ё" then -- specify that the past passive participle has ё instead of е if data.yo then error("Saw ё twice") end if not m_table.contains(allowed, "ё") then error("Variant " .. var .. " not allowed for this verb class") end data.yo = true elseif var == "о" then -- specify that the past passive participle has о instead of е -- NOTE: Not currently allowed as a user-specifiable variant if data.o then error("Saw о twice") end if not m_table.contains(allowed, "о") then error("Variant " .. var .. " not allowed for this verb class") end data.o = true elseif var == "жд" then -- specify that the past passive participle of class 4/5/6 verbs -- iotates -д to -жд instead of -ж if data.zhd then error("Saw жд twice") end if not m_table.contains(allowed, "жд") then error("Variant " .. var .. " not allowed for this verb class") end data.zhd = true else error("Unrecognized variant spec: " .. var) end variant_title = variant_title .. (variant_to_title[var] or "") return "" end) variant_title = rsub(variant_title, "%[⑤%]%[⑥%]", "[⑤⑥]") end if variants ~= "" and not m_table.contains(allowed, "past") then error("Past stress " .. variants .. " not allowed for this verb class") end if data.yo and not data.ppp then error("Variant ё specified without calling for past passive participle") end if data.o and not data.ppp then error("Variant о specified without calling for past passive participle") end if data.zhd and not data.ppp then error("Variant жд specified without calling for past passive participle") end if data.perf and not data.ppp and not data.ppp_override and not data.shouldnt_have_ppp and not data.impers then error("For perfective transitive verbs, need to specify past passive participle by variant or override; use |ppp=- if no such participle") end data.past_stress = variants == "" and "a" or rsub(variants, "/", "") data.title = data.title .. prepare_past_stress_indicator(data.past_stress) .. variant_title if data.star then data.title = rsub(data.title, "^([0-9]+°?)", "%1*") end -- If there's an override of past_pasv_part, generate the normal participle -- so we can determine whether the override is irregular. But set a flag -- so we erase any automatically generated past passive participles that -- aren't overridden. This happens for example in обнять, where there are -- two automatically generated past passive participles but a single -- ppp=о́внятый override. if not data.ppp and data.main_ppp_override then data.ppp = "+p" data.ppp_auto_generated = true end end local function set_past_by_stress(forms, past_stresses, prefix, prefixtr, base, basetr, args, data, no_pastml, note) -- If there isn't manual translit for the prefix, we need to supply it -- if there's manual translit for the base, because we often concatenate -- prefix to the base. local prefixtr = prefixtr or basetr and com.translit(prefix) for _, past_stress in ipairs(rsplit(past_stresses, ",")) do local pastml = no_pastml and "" or "л" local stressed_prefix, stressed_prefixtr if prefix == "пере" then stressed_prefix = "пе́ре" stressed_prefixtr = "pe" .. AC .. "re" elseif prefix == "раз" then stressed_prefix = "ро́з" stressed_prefixtr = "ro" .. AC .. "z" elseif prefix == "рас" then -- Does this ever occur? stressed_prefix = "ро́с" stressed_prefixtr = "ro" .. AC .. "s" elseif prefix == "ра" and rfind(base, "^[сз]") then -- Type 9/11/14/16 with automatically split prefix; may never happen. stressed_prefix = "ро́" stressed_prefixtr = "ro" .. AC else stressed_prefix, stressed_prefixtr = com.make_ending_stressed(prefix, prefixtr) end -- Normally the base is stressed and the prefix isn't, but it could -- be the other way around, e.g. in запереть and запереться, where -- the stress on the prefix is used to get prefix-stressed participles. -- To deal with this, we usually combine base and prefix unchanged, -- but in combination with stressed_prefix we always want an unstressed -- base, and when a stressed -ся́ is called for, we want both of them -- unstressed. local ubase, ubasetr = com.make_unstressed(base, basetr) local uprefix, uprefixtr = com.make_unstressed(prefix, prefixtr) -- If the prefix is stressed (вы́-), we need to use the unstressed base to avoid getting double stress. local prefixbase = com.is_stressed(prefix) and prefix .. ubase or prefix .. base local prefixbasetr = basetr and (com.is_stressed(prefix) and prefixtr .. ubasetr or prefixtr .. basetr) local stressed_prefix_ubase = stressed_prefix .. ubase local stressed_prefix_ubasetr = ubasetr and stressed_prefixtr .. ubasetr local uprefixubase = uprefix .. ubase local uprefixubasetr = ubasetr and uprefixtr .. ubasetr if past_stress == "a" then -- (/под/пере/при/по)забы́ть, раздобы́ть, (/пере/по)забы́ться append_past(forms, prefixbase, prefixbasetr, pastml, "ла", "ло", "ли", note) elseif past_stress == "a(1)" then -- вы́дать, вы́быть, etc.; also проби́ть with the meaning -- "to strike (of a clock)" (which is a(1),a or similar) append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) -- Retraction to prefix doesn't happen in feminine singular, see the -- bottom of page 81 of Zaliznyak's 1980 grammar. append_past(forms, prefixbase, prefixbasetr, {}, "ла", {}, {}, note) elseif past_stress == "b" then append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", "ло́", "ли́", note) elseif past_stress == "b*" then if not data.refl then error("Only reflexive verbs can take past stress variant " .. past_stress) end -- See comment in type c''. We want to see whether we actually -- added an argument, and if so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. (note or ""))) if argset and not args[argset] and not data.impers then data.default_reflex_stress = "ся́" end append_past(forms, prefixbase, prefixbasetr, {}, "ла́", "ло́", "ли́", note) elseif past_stress == "c" then -- изда́ть, возда́ть, сдать, пересозда́ть, воссозда́ть, надда́ть, наподда́ть, etc. -- быть, избы́ть, сбыть -- клясть, закля́сть append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", "ло", "ли", note) elseif past_stress == "c(1)" then -- прибы́ть, убы́ть -- прокля́сть -- also, c(1),c: -- зада́ть, обда́ть, отда́ть, подда́ть, переда́ть (пе́редал), преда́ть, прода́ть, разда́ть (ро́здал), созда́ть, etc. -- отбы́ть, побы́ть, пробы́ть -- also, c,c(1): -- добы́ть -- Because the prefix may vary depending on stress (esp. for -- раздать [ро́здал/раздала́]), we need to separate the endings that -- take the stressed prefix and those that take the unstressed -- prefix with stressed ending. append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) append_past(forms, prefixbase, prefixbasetr, {}, "ла́", {}, {}, note) elseif past_stress == "c'" then -- дать --same with "взять" append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", {"ло", "ло́"}, "ли", note) elseif past_stress == "c''" or past_stress == "c''-nd" or past_stress == "c''-bd" then if not data.refl then error("Only reflexive verbs can take past stress variant " .. past_stress) end -- c'' (-ся́ dated): all verbs in -да́ться; избы́ться, сбы́ться; all verbs in -кля́сться -- c''-nd (-ся́ not dated): various verbs in -ня́ться per Zaliznyak -- c''-bd (-ся́ becoming dated): various verbs in -ня́ться per ruwikt local note_symbol = past_stress == "c''-nd" and "" or next_note_symbol(data) append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", {"ло́", "ло"}, {"ли́", "ли"}) -- We want to see whether we actually added an argument, and if -- so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. note_symbol .. (note or ""))) -- Only display the internal note and set the default reflex -- stress if the form with the note will be displayed (i.e. not -- impersonal, and no override of this form). FIXME: We should -- have a more general mechanism to check for this. if not args[argset] and not data.impers then local note = past_stress == "c''" and note_symbol .. " Dated." or past_stress == "c''-bd" and note_symbol .. " Becoming dated." or nil if note then m_table.insertIfNot(data.internal_notes, note) end data.default_reflex_stress = "ся́" end elseif past_stress == "c''(1)" then -- запере́ться -- See comment in type c''. We want to see whether we actually -- added an argument, and if so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. (note or ""))) if argset and not args[argset] and not data.impers then data.default_reflex_stress = "ся́" end append_past(forms, prefixbase, prefixbasetr, {}, "ла́", "ло́", "ли́", note) append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) else error("Unrecognized past-stress value " .. past_stress .. ", should be a, a(1), b, b*, c, c(1), c', c'', c''-nd, c''-bd, c''(1) or comma-separated list") end end end -- Split a verb stem into a possibly multisyllabic prefix (пере-, переиз-, -- воссоз-, повы́-, etc.) and a single-syllable main verb (-тер-, -ли́-, -гре́-, -- etc.). Normally the splitting is done simply by looking for alternating -- vowel/consonant sequences, meaning that e.g. разгре́ will be split as -- ра + згре́ and растер will be split as ра + стер. For most purposes, this -- doesn't matter, but for the * variant it does; in that case, if it is -- known that the main verb base always begins with a single consonant, -- specify SINGLE_CONS_BASE and then e.g. растер will be split as рас + тер. local function split_monosyllabic_main_verb(ru, tr, single_cons_base) local rusyl, trsyl = com.split_syllables(ru, tr) local last_ru = rusyl[#rusyl] local last_tr = trsyl and trsyl[#trsyl] table.remove(rusyl, #rusyl) local prefix_ru = table.concat(rusyl, "") local prefix_tr if trsyl then table.remove(trsyl, #trsyl) prefix_tr = table.concat(trsyl, "") end if single_cons_base then local cons_to_move, rest = rmatch(last_ru, "^([" .. com.cons .. "]+)([" .. com.cons .. "].*)$") if cons_to_move then prefix_ru = prefix_ru .. cons_to_move last_ru = rest end if last_tr then cons_to_move, rest = rmatch(last_tr, "^([" .. com.tr_cons .. "]+)([" .. com.tr_cons .. "].*)$") if cons_to_move then prefix_tr = prefix_tr .. cons_to_move last_tr = rest end end end return prefix_ru, prefix_tr, last_ru, last_tr end local function split_known_main_verb(arg, mains) -- Given an argument (which may be RUSSIAN//TR), split the prefix from -- the main verb, which should be one of the verbs in MAINS (which can be -- a -- single verb or a list of verbs, but in either case all verbs -- need to be stressed). This correctly handles stressed and unstressed -- prefixes. local stem, tr = com.split_russian_tr(arg) if type(mains) ~= "table" then mains = {mains} end for _, main in ipairs(mains) do assert(com.is_stressed(main)) if rfind(stem, main .. "$") then stem, tr = com.strip_ending(stem, tr, main) if com.is_stressed(stem) then error("Two stresses in " .. arg) end return stem, tr, main, nil end main = com.make_unstressed_once(main) if rfind(stem, main .. "$") then stem, tr = com.strip_ending(stem, tr, main) if com.is_unstressed(stem) then error("No stresses in " .. arg) end return stem, tr, main, nil end end if #mains == 1 then error("Argument " .. arg .. " doesn't end in " .. mains[1]) else error("Argument " .. arg .. " doesn't end in any of " .. table.concat(mains, ",")) end end local function construct_long_prefix_variant(prefix) if rfind(prefix, "рас$") then return rsub(prefix, "рас$", "разо") end if rfind(prefix, "ис$") then return rsub(prefix, "ис$", "изо") end if rfind(prefix, "вс$") then return rsub(prefix, "вс$", "взо") end return prefix .. "о" end local function append_imper_by_variant(forms, stem, tr, variant, verbclass, note) local vowel_stem = is_vowel_stem(stem) local stress = rmatch(verbclass, "([abc])$") if not stress then error("Unrecognized verb class '" .. verbclass .. "', should end with a, b or c") end local longend = stress == "a" and "и" or "и́" local shortend = vowel_stem and (com.is_unstressed(stem) and "́й" -- accent on previous vowel or "й") or "ь" local function append_short_imper() append_imper(forms, stem, tr, shortend, shortend .. "те", note) end local function append_long_imper() append_imper(forms, stem, tr, longend, longend .. "те", note) end if variant and variant ~= "" then track("explicit-imper") track("explicit-imper/" .. verbclass) end if variant == "(2)" then -- use short variants with вы́- (for these verbs, long is expected) if not rfind(stem, "^вы́-") then error("Should only specify imperative variant (2) with verbs in вы́-, not " .. stem) end append_short_imper() elseif variant == "[(2)]" then -- use both long and short variants append_long_imper() append_short_imper() elseif variant == "(3)" then -- long in singular, short in plural append_imper(forms, stem, tr, longend, shortend .. "те", note) elseif variant == "[(3)]" then -- long and short in singular, short in plural append_imper(forms, stem, tr, {longend, shortend}, shortend .. "те", note) elseif variant == "ь" or variant == "й" then -- short variants wanted append_short_imper() elseif variant == "и" then -- long variants wanted append_long_imper() else assert(not variant or variant == "") if vowel_stem then if verbclass == "4b" or verbclass == "4c" or ( verbclass == "4a" and rfind(stem, "^вы́-")) then append_long_imper() else append_short_imper() end else -- consonant stem if stress == "b" or stress == "c" then append_long_imper() else assert(stress == "a") -- "и" after вы́-, e.g. вы́садить -- "и" after final щ, e.g. тара́щиться (although this particular -- verb has a [(3)] spec attached to it) if rfind(stem, "^вы́-") or rfind(stem, "щ$") or -- "и" after two consonants in a row (мо́рщить, зафре́ндить) rfind(stem, "[бвгджзклмнпрстфхцчшщь][бвгджзклмнпрстфхцчшщ]$") then append_long_imper() else -- "ь" after a single consonant (бре́дить) append_short_imper() end end end end end -- Compute the past passive participle stem for verbs that require it to be -- iotated (class 4, and class 5 in -еть). local function iotated_ppp(data, stem, tr) local iotated_stem, iotated_tr if data.zhd then local subbed iotated_stem, subbed = rsubb(stem, "з?д$", "жд") if not subbed then error("Variant -жд- specified but stem " .. stem .. " doesn't end in -д") end if tr then iotated_tr, subbed = rsubb(tr, "z?d$", "žd") if not subbed then error("Variant -жд- specified but translit " .. tr .. " doesn't end in -d") end end else iotated_stem, iotated_tr = com.iotation(stem, tr, data.shch) end return iotated_stem, iotated_tr end -- Set the past passive participle of verbs where the stress is moved left -- from the ending by one syllable (if possible) if the ending is stressed, -- otherwise left as-is (except class 1a in -е́ть, which has ending-stressed -- -ённый). This applies to classes 1, 2, 3, 5, 6, 10 and 13. The stem comes -- from the infinitive, iotated in class 5 -еть/-ѣть verbs. The participle -- ending is -анный/-янный for verbs in -ать/-ять, -енный/-ённый for verbs in -еть, -- -ѣнный/-ѣ̈нный for verbs in -ѣть, otherwise -тый. local function set_moving_ppp(forms, data) if not data.ppp then return end -- NOTE: No need to check for multiple infinitives because no verbs have -- them normally, and we probably don't want to check for overrides here -- (e.g. it would break достичь and related verbs, which have participles -- based on the infinitive достигнуть). local infinitive, infinitivetr = extract_russian_tr(forms["infinitive"]) local stem, ending = rmatch(infinitive, "^(.*)([аеѣоуя]́?ть)$") if not stem then error("Strange infinitive " .. infinitive .. " when trying to create participle") end local tr, endingtr if infinitivetr then if ending == "ять" or ending == "я́ть" then tr, endingtr = rmatch(infinitivetr, "^(.*)(ja" .. AC .. "?tʹ)$") else tr, endingtr = rmatch(infinitivetr, "^(.*)([aeěou]" .. AC .. "?tʹ)$") end if not tr then error("Translit " .. infinitivetr .. " doesn't match Cyrillic " .. infinitive) end end local ending_vowel = usub(ending, 1, 1) local ppptype = data.ppp if com.is_nonsyllabic(stem) then -- e.g. 3b гну́ть (гну́тый); but not -нуть (type 3a, as a suffix) ppptype = "(7)" end if m_table.contains({"5a", "5b", "5c"}, data.conj_type) and (ending_vowel == "е" or ending_vowel == "ѣ") then stem, tr = iotated_ppp(data, stem, tr) end if not com.is_stressed(stem) then stem, tr = com.make_ending_stressed(stem, tr) end if data.o then -- цев -> цо́в, e.g. (об)лицева́ть -> (об)лицо́ванный stem = rsub(stem, "е́", "о́") -- Cyrillic if tr then tr = rsub(tr, "e" .. AC, "o" .. AC) -- Latin end elseif data.yo then -- ё occurs with e.g. 1a наверста́ть (навёрстанный) -- ё occurs with e.g. 3b поверну́ть (повёрнутый) -- ё occurs with e.g. 5b лежа́ть (лёжанный) but not with 5c держа́ть -- (де́ржанный) -- ё occurs always with class 2 in -ева́ть, e.g. -- (за)тушева́ть ((за)тушёванный) and (за)клева́ть ((за)клёванный) local subbed stem, subbed = rsubb(stem, "е́", "ё") -- Cyrillic if not subbed and data.old then stem, subbed = rsub(stem, "ѣ́", "ѣ̈") end if not subbed then error("No stressed е" .. (data.old and " or ѣ" or "") .. " in stem " .. stem .. " to replace with ё" .. (data.old and " or ѣ̈" or "") .. " when trying to create participle") end if tr then tr, subbed = rsub(tr, "j[eě]" .. AC, "jo" .. AC) -- Latin if not subbed then tr, subbed = rsub(tr, "[eě]" .. AC, "jo" .. AC) -- Latin end if not subbed then error("No stressed е in translit " .. tr .. " to replace with jo when trying to create participle") end end end if data.conj_type == "1a" and ending_vowel == "е" then -- 1a, only одоле́ть, преодоле́ть, verbs in -печатле́ть set_ppp(forms, stem, tr, "ённый") elseif data.conj_type == "1a" and ending_vowel == "ѣ" then set_ppp(forms, stem, tr, "ѣ̈нный") else local stressed_ending, unstressed_ending if ending_vowel == "е" then stressed_ending = "ённый" unstressed_ending = "енный" elseif ending_vowel == "ѣ" then stressed_ending = "ѣ̈нный" unstressed_ending = "ѣнный" else local ppp_ending = (ending_vowel == "а" or ending_vowel == "я") and "нный" or "тый" stressed_ending = ending_vowel .. AC .. ppp_ending unstressed_ending = ending_vowel .. ppp_ending end set_ppp(forms, stem, tr, -- (7) occurs with 1a обуя́ть (обуя́нный) ppptype == "(7)" and stressed_ending or -- [(7)] -- when does it occur? may only occur in class 4 ppptype == "[(7)]" and {unstressed_ending, stressed_ending} or unstressed_ending) end end -- Iterate over the values of a property (e.g. past_m, past_f), handling -- overrides properly. Call FN on each one, passing in RU, TR, NOTE. local function iterate_over_prop(forms, args, prop, fn) for _, form in ipairs(main_to_all_verb_forms[prop]) do local ru, tr if args[form] then local orig_forms = {} for _, form2 in ipairs(main_to_all_verb_forms[prop]) do if forms[form2] then table.insert(orig_forms, forms[form2]) end end local override = parse_and_stress_override(form, args[form], forms[form], orig_forms) ru, tr = extract_russian_tr(override) end if (not ru or ru == "" or ru == "-") and forms[form] then ru, tr = extract_russian_tr(forms[form]) end -- skip unstressed forms (may occur in the past_m when a stressed -- reflexive -ся́ should occur; these occur only in запереться and -- опереться, where they're used to generate the past active part -- and past adverbial part, and end-stressed forms shouldn't be -- generated) if ru and ru ~= "" and ru ~= "-" and not com.is_unstressed(ru) then local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) end fn(ruentry, trentry, {runotes, trnotes}) end end end -- Set the past passive participle for those classes where it is derived -- from the past tense masculine singular (9, 11, 12, 14, 15, 16). We need -- to apply any relevant overrides. local function set_ppp_from_past_m(forms, args, data) if not data.ppp then return end iterate_over_prop(forms, args, "past_m", function(ru, tr, note) if rfind(ru, "л$") then ru = rsub(ru, "л$", "") if tr then tr = rsub(tr, "l$", "") end end append_ppp(forms, ru, tr, "тый", note) end) end -- Set the past passive participle for class-4 verbs. local function set_class_4_ppp(forms, data, stem, tr, vclass) if not data.ppp then return end local iotated_stem, iotated_tr = iotated_ppp(data, stem, tr) vclass = vclass or data.conj_type if vclass == "4b" then local stressed_iotated_stem, stressed_iotated_tr = com.make_ending_stressed(iotated_stem, iotated_tr) set_ppp(forms, stressed_iotated_stem, stressed_iotated_tr, -- (8) occurs with 4b скрои́ть (скро́енный) data.ppp == "(8)" and "енный" or -- [(8)] occurs with 4b разгроми́ть (разгромлённый, разгро́мленный) data.ppp == "[(8)]" and {"ённый", "енный"} or "ённый") else set_ppp(forms, iotated_stem, iotated_tr, -- (7) occurs with 4c раздели́ть (разделённый) data.ppp == "(7)" and "ённый" or -- [(7)] occurs with 4a осве́домить (осве́домленный, осведомлённый) -- [(7)] occurs with 4c иссуши́ть (иссу́шенный, иссушённый) data.ppp == "[(7)]" and {"енный", "ённый"} or "енный") end end -- Set the past passive participle for class-7 and class-8 verbs. These -- form the PPP by adding to the base of the 3sg pres/futr (i.e. minus -- -ет/-ёт). The stress follows the stress of the past singular feminine. -- Only types a, a(1) and b exist, meaning that if the past singular feminine -- is ending-stressed then the PPP ending is -ённый, otherwise it is -енный -- with the stress of the 3sg pres/futr base preserved (and added to the -- last syllable if the base has no stress, as in 7b укра́сть, 3sg украдёт, -- fem sg past укра́ла, PPP укра́денный). local function set_class_7_8_ppp(forms, args, data) if not data.ppp then return end local sg3_bases = {} -- Extract 3sg bases. There may be more than one possible form, e.g. in -- обокра́сть, so support this. -- FIXME: We don't support checking for overrides here; doing so isn't -- overly hard but is a bit tricky because the overrides will be either -- pres_3sg or futr_3sg, depending on the aspect of the verb. -- FIXME: We don't support manual translit here, because neither 7 nor 8 -- support it elsewhere. for _, form in ipairs(main_to_all_verb_forms["pres_futr_3sg"]) do local ru, tr if forms[form] then ru, tr = extract_russian_tr(forms[form]) end if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) ruentry = rsub(ruentry, "[её]т$", "") if com.is_unstressed(ruentry) then ruentry = com.make_ending_stressed(ruentry) end m_table.insertIfNot(sg3_bases, {ruentry, runotes}) end end -- Here we do the same rigmarole as in set_ppp_from_past_m(), to respect -- any past_f overrides that might have been set. It's unlikely that -- there is more than one possible form but we support it. iterate_over_prop(forms, args, "past_f", function(ru, tr, note) for _, base_and_notes in ipairs(sg3_bases) do local base, notes = base_and_notes[1], base_and_notes[2] append_ppp(forms, base, nil, -- check if past_f is ending-stressed rfind(ru, AC .. "$") and "ённый" or "енный", notes) end end) end --[=[ Conjugation functions ]=] conjugations["1a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7", "ё"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) if stem == "-" and not tr then -- Template space; leave it else stem, tr = com.strip_ending(stem, tr, "ть") end no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "ть") append_participles(forms, stem, tr, "ющий", "емый", "я", "вший", "вши", "в") set_moving_ppp(forms, data) present_je(forms, stem, tr, "a") append_imper(forms, stem, tr, "й", "йте") set_past(forms, stem, tr, "л", "ла", "ло", "ли") return forms end local function guts_of_2(args, data) local forms = {} local inf_stem, inf_tr = com.split_russian_tr(get_stressed_arg(args, 2)) inf_stem, inf_tr = com.strip_ending(inf_stem, inf_tr, "ть") no_stray_args(args, 2) local pres_stem, pres_tr = inf_stem, inf_tr local variants = args[1] or "" parse_variants(data, variants, {"+p", "7"}) -- If stem ends in -ева́ть and a past passive participle is called for -- with stress on the -е-, automatically set -о- or -ё- as required. if data.ppp and data.ppp ~= "(7)" then if rfind(inf_stem, "цева́") then if data.ppp == "[(7)]" then -- FIXME. Theoretically we should support this but there -- aren't any verbs requiring it. It won't work properly -- currently because we need the о to appear only when -- stressed. error("Variant [(7)] not supported for class 2") end -- цев -> цо́в, e.g. (об)лицева́ть -> (об)лицо́ванный data.o = true data.title = data.title .. "(-о-)" elseif rfind(inf_stem, "ева́") then data.yo = true data.title = data.title .. "(-ё-)" end end -- all -ова- change to -у- pres_stem = rsub(pres_stem, "о(́?)ва(́?)$", "у%1%2") pres_tr = pres_tr and rsub(pres_tr, "o(́?)va(́?)$", "u%1%2") -- -ева- change to -ю- after most consonants and vowels, to -у- after hissing sounds and ц if rfind(pres_stem, "[бвгдзклмнпрстфхь" .. com.vowel .. AC .. "]е(́?)ва(́?)$") then pres_stem = rsub(pres_stem, "е(́?)ва(́?)$", "ю%1%2") pres_tr = pres_tr and rsub(pres_tr, "e(́?)va(́?)$", "ju%1%2") elseif rfind(pres_stem, "[жцчшщ]е(́?)ва(́?)$") then pres_stem = rsub(pres_stem, "е(́?)ва(́?)$", "у%1%2") pres_tr = pres_tr and rsub(pres_tr, "e(́?)va(́?)$", "u%1%2") end forms["infinitive"] = combine(inf_stem, inf_tr, "ть") if data.conj_type == "2a" then append_participles_2stem(forms, pres_stem, pres_tr, inf_stem, inf_tr, "ющий", "емый", "я", "вший", "вши", "в") present_je(forms, pres_stem, pres_tr, "a") else append_participles_2stem(forms, pres_stem, pres_tr, inf_stem, inf_tr, "ю́щий", "-", "я́", "вший", "вши", "в") present_je(forms, pres_stem, pres_tr, "b") end set_moving_ppp(forms, data) append_imper(forms, pres_stem, pres_tr, "й", "йте") set_past(forms, inf_stem, inf_tr, "л", "ла", "ло", "ли") return forms end conjugations["2a"] = function(args, data) return guts_of_2(args, data) end conjugations["2b"] = function(args, data) return guts_of_2(args, data) end conjugations["3°a"] = function(args, data) local forms = {} -- (5), [(6)] or similar; imperative indicators parse_variants(data, args[1], {"5", "6", "23", "и", "+p", "7", "ё"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = com.strip_ending(stem, tr, "нуть") local vowel_stem = is_vowel_stem(stem) no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "нуть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "нущий", "-", "-", data.var6 == "req" and "нувший" or data.var6 == "opt" and (vowel_stem and {"вший", "нувший"} or {"ший", "нувший"}) or vowel_stem and "вший" or "ший", data.var6 == "req" and "нувши" or data.var6 == "opt" and (vowel_stem and {"вши", "нувши"} or {"ши", "нувши"}) or vowel_stem and "вши" or "ши", data.var6 == "req" and "нув" or data.var6 == "opt" and (vowel_stem and {"в", "нув"} or "нув") or vowel_stem and "в" or "-") set_moving_ppp(forms, data) present_e_a(forms, stem .. "н", tr and tr .. "n") append_imper_by_variant(forms, stem .. "н", tr and tr .. "n", data.imper_variant, "3°a") forms["past_m"] = data.var5 and combine(stem, tr, "нул") or "-" forms["past_m_short"] = data.var5 ~= "req" and combine(stem, tr, (vowel_stem and "л" or "")) or nil forms["past_f_short"] = combine(stem, tr, "ла") forms["past_n_short"] = combine(stem, tr, "ло") forms["past_pl_short"] = combine(stem, tr, "ли") return forms end conjugations["3a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"23", "и", "+p", "7", "ё"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) -- make sure we can strip нуть from the stem and any translit; com.strip_ending(stem, tr, "нуть") -- but then just strip the -уть and leave the н stem, tr = com.strip_ending(stem, tr, "уть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "уть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "ущий", "-", "-", "увший", "увши", "ув") set_moving_ppp(forms, data) present_e_a(forms, stem, tr) append_imper_by_variant(forms, stem, tr, data.imper_variant, "3a") set_past(forms, stem .. "ул", tr and tr .. "ul", "", "а", "о", "и") return forms end local function guts_of_3b_3c(args, data, vclass) local forms = {} parse_variants(data, args[1], {"+p", "7", "ё"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) -- make sure we can strip нуть from the stem and any translit; com.strip_ending(stem, tr, "ну́ть") -- but then just strip the -у́ть and leave the н stem, tr = com.strip_ending(stem, tr, "у́ть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "у́ть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "у́щий", "-", "-", "у́вший", "у́вши", "у́в") set_moving_ppp(forms, data) append_imper(forms, stem, tr, "и́", "и́те") set_past(forms, stem, tr, "у́л", "у́ла", "у́ло", "у́ли") if data.conj_type == "3b" then present_e_b(forms, stem, tr) else stem, tr = com.make_ending_stressed(stem, tr) present_e_c(forms, stem, tr) end return forms end conjugations["3b"] = function(args, data) return guts_of_3b_3c(args, data) end conjugations["3c"] = function(args, data) return guts_of_3b_3c(args, data) end conjugations["4a"] = function(args, data) local forms = {} -- imperative variants, also щ, used for verbs like похитить (похи́щу) (4a), -- защитить (защищу́) (4b), поглотить (поглощу́) (4c) with a different -- iotation (т -> щ, not ч) parse_variants(data, args[1], {"23", "и", "щ", "past", "+p", "7", "жд"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = com.strip_ending(stem, tr, "ить") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "ить") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") append_participles(forms, stem, tr, hushing and "ащий" or "ящий", "awkward-имый", hushing and "а" or "я", "ивший", "ивши", "ив") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "a", data.shch) append_imper_by_variant(forms, stem, tr, data.imper_variant, "4a") -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem .. "и", tr and tr .. "i", args, data) return forms end conjugations["4a1a"] = function(args, data) local forms = {} data.title = "4a // 1a" data.cat_conj_types = {"1a", "4a"} -- imperative variants, also щ, used for verbs like похитить (похи́щу) (4a), -- защитить (защищу́) (4b), поглотить (поглощу́) (4c) with a different -- iotation (т -> щ, not ч) parse_variants(data, args[1], {"23", "и", "щ", "past", "+p", "7", "жд"}) local stem4, tr4 = com.split_russian_tr(get_stressed_arg(args, 2)) stem4, tr4 = com.strip_ending(stem4, tr4, "ить") local hushing = rfind(stem4, "[шщжч]$") local stem1, tr1 if hushing then stem1 = stem4 .. "а" tr1 = tr4 and tr4 .. "a" else stem1 = stem4 .. "я" tr1 = tr4 and tr4 .. "ja" end no_stray_args(args, 2) forms["infinitive"] = combine(stem4, tr4, "ить") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. append_participles(forms, stem4, tr4, hushing and "ащий" or "ящий", "awkward-имый", hushing and "а" or "я", "ивший", "ивши", "ив") append_participles(forms, stem1, tr1, "ющий", "емый", "я", {}, {}, {}) set_class_4_ppp(forms, data, stem4, tr4) present_i(forms, stem4, tr4, "a", data.shch) present_je(forms, stem1, tr1, "a", data.shch) append_imper_by_variant(forms, stem4, tr4, data.imper_variant, "4a") append_imper(forms, stem1, tr1, "й", "йте") -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem4 .. "и", tr4 and tr4 .. "i", args, data) return forms end conjugations["4b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"щ", "past", "+p", "8", "жд"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = com.strip_ending(stem, tr, "и́ть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "и́ть") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") append_participles(forms, stem, tr, hushing and "а́щий" or "я́щий", "awkward-и́мый", hushing and "а́" or "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "b", data.shch) append_imper(forms, stem, tr, "и́", "и́те") -- set prefix to "" as past stem may vary in length and no (1) variants local stem_noa, tr_noa = com.make_unstressed_once(stem, tr) set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "и́", tr_noa and tr_noa .. "i" .. AC, args, data) return forms end conjugations["4c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"щ", "4", "past", "+p", "7", "жд"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = com.strip_ending(stem, tr, "и́ть") stem, tr = com.make_ending_stressed(stem, tr) no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "и́ть") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") local prap_end_stressed = hushing and "а́щий" or "я́щий" local prap_stem_stressed = hushing and "ащий" or "ящий" append_participles(forms, stem, tr, data.var4 == "req" and prap_stem_stressed or data.var4 == "opt" and {prap_end_stressed, prap_stem_stressed} or prap_end_stressed, "awkward-и́мый", hushing and "а́" or "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "c", data.shch) append_imper(forms, stem, tr, "и́", "и́те") local stem_noa, tr_noa = com.make_unstressed_once(stem, tr) set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "и́", tr_noa and tr_noa .. "i" .. AC, args, data) return forms end -- Combined class 5. But there's enough conditional code that it might make -- more sense to separate them again. local function guts_of_5(args, data) local forms = {} local is5a = data.conj_type == "5a" local is5b = data.conj_type == "5b" -- imperative ending (выгнать - выгони) and past stress; imperative is -- "й" after any vowel (e.g. выстоять), with or without an acute accent, -- otherwise ь or и if is5a or is5b then parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё"}) else parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё", "4"}) end local inf = get_stressed_arg(args, 2) local past_stem = com.strip_ending(inf, nil, "ть") local stem = is5b and get_opt_unstressed_arg(args, 3) or get_opt_stressed_arg(args, 3) local default_stem = rmatch(past_stem, "^(.*)[еѣая]́?$") if not default_stem then error("Argument " .. inf .. " doesn't end in еть, ѣть, ать or ять") end if not is5a and not is5b then default_stem = com.make_ending_stressed(default_stem) end stem = stem or default_stem local pres_note = stem ~= default_stem and IRREG no_stray_args(args, 3) forms["infinitive"] = past_stem .. "ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") if is5a then append_participles_2stem(forms, stem, nil, past_stem, nil, hushing and "ащий" or "ящий", "имый", hushing and "а" or "я", "вший", "вши", "в", pres_note) elseif is5b then append_participles_2stem(forms, stem, nil, past_stem, nil, hushing and "а́щий" or "я́щий", "и́мый", hushing and "а́" or "я́", "вший", "вши", "в", pres_note) else -- var4 occurs with at least терпре́ть and дыша́ть local prap_end_stressed = hushing and "а́щий" or "я́щий" local prap_stem_stressed = hushing and "ащий" or "ящий" append_participles_2stem(forms, stem, nil, past_stem, nil, data.var4 == "req" and prap_stem_stressed or data.var4 == "opt" and {prap_end_stressed, prap_stem_stressed} or prap_end_stressed, "и́мый", hushing and "а́" or "я́", "вший", "вши", "в", pres_note) end set_moving_ppp(forms, data) present_i(forms, stem, nil, is5a and "a" or is5b and "b" or "c", nil, pres_note) append_imper_by_variant(forms, stem, nil, data.imper_variant, data.conj_type, pres_note) -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, past_stem, nil, args, data) return forms end conjugations["5a"] = function(args, data) return guts_of_5(args, data) end conjugations["5b"] = function(args, data) return guts_of_5(args, data) end conjugations["5c"] = function(args, data) return guts_of_5(args, data) end -- Implement 6a, 6°a, 6a1as13, 6a1as14, and 1a6a. local function guts_of_6a(args, data, vclass) local forms = {} -- Type 6a1a, section 13: -- Forms of both 6a and 1a can occur. They are the same in the infinitive -- and past. In the present active participle and the present/future, the -- type 6 forms are preferred and the type 1a forms are colloquial. In the -- remaining present forms and the imperative, both are equally preferred -- (we put the type-6 forms first because Zaliznyak lists them first). -- Type 6a1a section 14, type 1a6a: -- Forms of both 6a and 1a can occur. They are the same in the infinitive -- and past. In the present adverbial participle and the imperative, the -- type 1a forms are preferred and the type 6a forms are dated. In the -- remaining present forms, one or the other is slightly preferred (type -- 6a for 6a1a, type 1a for 1a6a). if vclass == "6a1as13" or vclass == "6a1as14" then data.title = "6a // 1a" data.cat_conj_types = {"1a", "6a"} elseif vclass == "1a6a" then data.title = "1a // 6a" data.cat_conj_types = {"1a", "6a"} end parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё"}) local inf = get_stressed_arg(args, 2) local inf_past_stem = com.strip_ending(inf, nil, "ть") local stem = rmatch(inf_past_stem, "^(.*)[ая]́?$") if not stem then error("Argument " .. inf .. " doesn't end in ать or ять") end if com.is_unstressed(stem) then -- колыха́ть, колеба́ть, etc. stem = com.make_ending_stressed(stem) end -- вызвать - вы́зову (в́ызов) local pres_stem = get_opt_stressed_arg(args, 3) or stem no_stray_args(args, 3) local pres_note = pres_stem ~= stem and IRREG -- no iotation, e.g. вырвать - вы́рву local no_iotation = vclass == "6°a" -- replace consonants for 1st person singular present/future local iotated_stem = no_iotation and pres_stem or com.iotation(pres_stem) forms["infinitive"] = inf_past_stem .. "ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") or no_iotation -- Participles -- pres_pasv_part is normal if infinitive ends in -ять, nonexistent except -- with certain lexical exceptions (колеба́ть, колыха́ть, глаго́лать, -- дви́гать with exceptional form дви́жимый) if infinitive ends in -ать local prpp_status = rfind(inf_past_stem, "я́?$") and "" or "none-" if vclass == "6a" or vclass == "6°a" or vclass == "6a1as13" then append_participles_2stem(forms, iotated_stem, nil, inf_past_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", hushing and "а" or "я", "вший", "вши", "в", pres_note) if vclass == "6a1as13" then -- then all the type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий*", prpp_status .. "емый", "я") end elseif vclass == "6a1as14" then -- first the preferred type 6a present active/passive participles append_participles(forms, iotated_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", {}, {}, {}, {}, pres_note) -- then all the type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий", "емый", "я", "вший", "вши", "в") -- then the dated type 6a present adverbial participle append_participles(forms, iotated_stem, nil, {}, {}, hushing and "а*" or "я*", {}, {}, {}, pres_note) else -- type 1a6a -- first the preferred type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий", "емый", "я", "вший", "вши", "в") -- then the type 6a forms (dated in present adverbial participle) append_participles(forms, iotated_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", hushing and "а*" or "я*", {}, {}, {}, pres_note) end set_moving_ppp(forms, data) -- Present/future tense local function class_6_present() if no_iotation then present_e_a(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "a", nil, pres_note) end end if vclass == "6a" or vclass == "6°a" then class_6_present() elseif vclass == "1a6a" then -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a") class_6_present() elseif vclass == "6a1as14" then class_6_present() -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a") else -- 6a1as13 class_6_present() -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a", nil, "*") end -- Imperative forms; if 1a6a or 6a1as14, type 6a forms are dated; -- if 6a1as13, type 6a forms go first. local function class_1_impr() append_imper(forms, inf_past_stem, nil, "й", "йте") end local function class_6_impr() local dated_note = ((vclass == "6a1as14" or vclass == "1a6a") and "*" or "") .. (pres_note or "") append_imper_by_variant(forms, iotated_stem, nil, data.imper_variant, "6a", dated_note) end if vclass == "6a1as14" or vclass == "1a6a" then class_1_impr() class_6_impr() elseif vclass == "6a1as13" then class_6_impr() class_1_impr() else class_6_impr() end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, inf_past_stem, nil, args, data) if vclass == "6a1as14" or vclass == "1a6a" then m_table.insertIfNot(data.internal_notes, "* Dated.") elseif vclass == "6a1as13" then m_table.insertIfNot(data.internal_notes, "* Colloquial; type-6 forms preferred.") end return forms end conjugations["6a"] = function(args, data) return guts_of_6a(args, data, "6a") end conjugations["6°a"] = function(args, data) return guts_of_6a(args, data, "6°a") end conjugations["6a1as13"] = function(args, data) return guts_of_6a(args, data, "6a1as13") end conjugations["6a1as14"] = function(args, data) return guts_of_6a(args, data, "6a1as14") end conjugations["1a6a"] = function(args, data) return guts_of_6a(args, data, "1a6a") end -- implement 6b, 6°b local function guts_of_6b(args, data, vclass) local forms = {} parse_variants(data, args[1], {"past", "+p", "7", "ё"}) local inf = get_stressed_arg(args, 2) local stem = rmatch(inf, "^(.*)[ая]́ть$") if not stem then error("Argument " .. inf .. " doesn't end in ать or ять") end -- звать - зов, драть - дер local pres_stem = get_opt_unstressed_arg(args, 3) or stem no_stray_args(args, 3) -- no iotation, e.g. рвать - рву local no_iotation = vclass == "6°b" local vowel_end_stem = is_vowel_stem(stem) local pres_note = pres_stem ~= stem and IRREG if no_iotation then present_e_b(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "b", nil, pres_note) end local impr_end = vowel_end_stem and "́й" -- accent on the preceding vowel or "и́" append_imper(forms, pres_stem, nil, impr_end, impr_end .. "те", pres_note) -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(pres_stem, "[шщжч]$") -- no pres_pasv_part local past_stem_with_vowel = stem .. (vowel_end_stem and "я́" or "а́") append_participles_2stem( forms, pres_stem, nil, past_stem_with_vowel, nil, ((hushing or no_iotation) and "у́щий" or "ю́щий"), {}, (hushing and "а́" or "я́"), "вший", "вши", "в", pres_note) forms["infinitive"] = combine(past_stem_with_vowel, nil, "ть") set_moving_ppp(forms, data) -- past_f for ждала́, подождала́ now handled through general mechanism --for разобрало́сь, past_n2 разобрало́ now handled through general mechanism --for разобрали́сь, past_pl2 разобрали́ now handled through general mechanism -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem .. (vowel_end_stem and "я́" or "а́"), nil, args, data) return forms end conjugations["6b"] = function(args, data) return guts_of_6b(args, data, "6b") end conjugations["6°b"] = function(args, data) return guts_of_6b(args, data, "6°b") end -- Implement 6c, 6°c and 6c1a. local function guts_of_6c(args, data, vclass) local forms = {} -- In type 6c1a, forms of both 6c and 1a can occur. They are -- the same in the infinitive and past. In the present active participle -- and the present/future, the type 6c forms are preferred and the type 1a -- forms are colloquial. In the remaining present forms and the imperative, -- both are equally preferred (we put the 6c forms first because Zaliznyak -- lists 6c first). if vclass == "6c1a" then data.title = "6c // 1a" data.cat_conj_types = {"1a", "6c"} end -- optional щ parameter for verbs like клеветать (клевещу́), past stress parse_variants(data, args[1], {"щ", "past", "+p", "7", "ё"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "а́ть") stem = com.make_ending_stressed(stem) -- разостла́ть - расстелю́, рассте́лешь local pres_stem = get_opt_stressed_arg(args, 3) or stem no_stray_args(args, 3) local pres_note = pres_stem ~= stem and IRREG -- remove accent for some forms local stem_noa = com.make_unstressed(stem) -- applies only to стона́ть, застона́ть, простона́ть local no_iotation = vclass == "6°c" -- iotate the stem local iotated_stem = no_iotation and pres_stem or com.iotation(pres_stem, nil, data.shch) local stem1a = stem_noa .. "а́" forms["infinitive"] = stem_noa .. "а́ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") -- Participles append_participles_2stem(forms, iotated_stem, nil, stem_noa, nil, (hushing or no_iotation) and "ущий" or "ющий", {}, hushing and "а́" or "я́", "а́вший", "а́вши", "а́в", pres_note) if vclass == "6c1a" then -- then all the type 1a forms (both are the same in the past) append_participles(forms, stem1a, nil, "ющий*", "емый", "я") end set_moving_ppp(forms, data) if no_iotation then present_e_c(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "c", data.shch, pres_note) end append_imper(forms, iotated_stem, nil, "и́", "и́те", pres_note) if vclass == "6c1a" then present_je(forms, stem1a, nil, "a", nil, "*") append_imper(forms, stem1a, nil, "й", "йте") end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "а́", nil, args, data) if vclass == "6c1a" then m_table.insertIfNot(data.internal_notes, "* Colloquial; type-6 forms preferred.") end return forms end conjugations["6c"] = function(args, data) return guts_of_6c(args, data, "6c") end conjugations["6°c"] = function(args, data) return guts_of_6c(args, data, "6°c") end conjugations["6c1a"] = function(args, data) return guts_of_6c(args, data, "6c1a") end local function convert_last_e_to_yo(form) return rsub(form, "([еѣ])[́̀̈]*([^" .. com.vowel .. "]*)$", function(e, nonvowels) return (e == "е" and "ё" or "ѣ̈") .. nonvowels end) end local function guts_of_7(args, data, forms) local is7b = data.conj_type == "7b" local full_inf = get_stressed_arg(args, 2) local pres_stems = is7b and get_unstressed_arg(args, 3) or get_stressed_arg(args, 3) pres_stems = rsplit(pres_stems, ",") local past_stem if past_stem ~= "ёе" then past_stem = get_opt_stressed_arg(args, 4) end local past_stem_vowel_alt = past_stem == "ёе" if past_stem_vowel_alt then past_stem = nil end no_stray_args(args, 4) forms["infinitive"] = full_inf -- Construct the default past and present stem by a combination of -- infinitive and present final consonant. -- (1) Deduce the final consonant. local final_cons for _, pres_stem in ipairs(pres_stems) do -- Final cons is -ст if pres stem ends in vowel + ст, else -- single final cons [дтсзбп] (no actual examples of final п). -- Note that final -з can occur after a consonant (e.g. ползти́). local this_final_cons = rmatch(pres_stem, "[" .. com.vowel .. "]" .. AC .. "?(ст)$") if not this_final_cons then this_final_cons = rmatch(pres_stem, "([дтсзбп])$") end if not this_final_cons then error("Unable to determine final consonant from present stem " .. pres_stem) end if final_cons and this_final_cons ~= final_cons then error("Present stems with conflicting final consonants specified: " .. table.concat(pres_stems, ",")) end final_cons = this_final_cons end -- (2) Find the infinitive minus the termination. local prefix = rmatch(full_inf, "^(.*)[сз]т[иь]" .. AC .."?$") if not prefix then error("Strange infinitive " .. full_inf .. "in class 7") end -- (3) Combine infinitive with final consonant. local default_pres_stem = prefix .. final_cons if is7b then default_pres_stem = com.make_unstressed(default_pres_stem) end local default_past_stem = default_pres_stem if com.is_unstressed(default_past_stem) then default_past_stem = com.make_ending_stressed(default_past_stem) end -- (4) Past stems ending in -д and -т when the infinitive ends in -сть (but not -сти or -сти́) -- lose this consonant (page 85 of Zaliznyak, see also footnote 2 on that page). if rfind(full_inf, "сть$") then default_past_stem = rsub(default_past_stem, "[дт]$", "") end -- (5) If 7b and the past stem wasn't originally specified as ёе, the past stem gets -- ё in place of е. if is7b and not past_stem_vowel_alt then default_past_stem = convert_last_e_to_yo(default_past_stem) end for _, pres_stem in ipairs(pres_stems) do local pres_note = pres_stem ~= default_pres_stem and IRREG if is7b then present_e_b(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и́", "и́те", pres_note) else present_e_a(forms, pres_stem, nil, pres_note) append_imper_by_variant(forms, pres_stem, nil, data.imper_variant, "7a", pres_note) end end -- Construct the past stem if not specified. Note that we then derive a separate -- past-tense stem from this stem, and this stem as such ends up applying only -- to the past active and adverbial participles. if not past_stem then past_stem = default_past_stem end local past_note = past_stem ~= default_past_stem and IRREG -- Derive the past tense stem from the past stem derived above. This has ё instead of е -- in 7b verbs; it also loses д and т in all cases, when the past stem derived above only loses -- these consonants in some cases. local past_tense_stem = past_stem if is7b then past_tense_stem = convert_last_e_to_yo(past_tense_stem) end past_tense_stem = rsub(past_tense_stem, "[дт]$", "") local vowel_pp = is_vowel_stem(past_stem) local pap = vowel_pp and "вши" or "ши" local var9_note_symbol = next_note_symbol(data) for _, pres_stem in ipairs(pres_stems) do local pres_note = pres_stem ~= default_pres_stem and IRREG append_participles_2stem(forms, pres_stem, nil, past_stem, nil, is7b and "у́щий" or "ущий", "-", is7b and "я́" or "я", vowel_pp and "вший" or "ший", data.var9 and {is7b and "я́" or "я", pap .. var9_note_symbol} or pap, vowel_pp and not data.var9 and "в" or "-", pres_note, past_note) end if data.var9 then m_table.insertIfNot(data.internal_notes, var9_note_symbol .. " Dated.") end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, past_tense_stem, nil, args, data, -- 0 ending if the past stem ends in a consonant not is_vowel_stem(past_tense_stem) and "no-pastml", past_note) -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) end conjugations["7a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"23", "и", "9","past", "+p"}) -- лезть - ле́зши - non-existent past_actv_part handled through general mechanism guts_of_7(args, data, forms) return forms end conjugations["7b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"9", "past", "+p"}) guts_of_7(args, data, forms) return forms end local function class_8a_stem_to_infinitive(stem) -- map e.g. вы́сек back to высе́чь return rsub(stem, "[гк]$", "чь") end local function class_8b_stem_to_infinitive(stem) -- map e.g. отвлёк back to отвле́чь -- map e.g. зажёг back to заже́чь return com.make_ending_stressed(rsub(rsub(rsub(stem, "ё", "е"), "ѣ̈", "ѣ"), "[гк]$", "чь")) end conjugations["8a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local full_inf = get_stressed_arg(args, 2) local stem = get_stressed_arg(args, 3) local stressed_past_stem = get_opt_stressed_arg(args, 4) or stem no_stray_args(args, 4) forms["infinitive"] = full_inf local pres_note = class_8a_stem_to_infinitive(stem) ~= full_inf and IRREG local stressed_past_note = class_8a_stem_to_infinitive(stressed_past_stem) ~= full_inf and IRREG -- default for pres_pasv_part is blank append_participles_2stem(forms, stem, nil, stressed_past_stem, nil, "ущий", "-", "-", "ший", "ши", "-", pres_note, stressed_past_note) local iotated_stem = com.iotation(stem) append_pres_futr(forms, iotated_stem, nil, {}, "ешь", "ет", "ем", "ете", {}, pres_note) append_pres_futr(forms, stem, nil, "у", {}, {}, {}, {}, "ут", pres_note) append_imper(forms, stem, nil, "и", "ите", pres_note) -- set prefix to "" as stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem, nil, args, data, "no-pastml", pres_note) forms["past_m"] = stressed_past_stem .. (stressed_past_note or "") -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) return forms end conjugations["8b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local full_inf = get_stressed_arg(args, 2) local stem = get_unstressed_arg(args, 3) local stressed_past_stems = rsplit(args[4] or "ё", ",") for _, stressed_past_stem in ipairs(stressed_past_stems) do if stressed_past_stem ~= "е" then check_stressed_arg(stressed_past_stem, 4) end end no_stray_args(args, 4) forms["infinitive"] = full_inf local pres_note = class_8b_stem_to_infinitive(stem) ~= full_inf and IRREG local iotated_stem = com.iotation(stem) append_pres_futr(forms, iotated_stem, nil, {}, "ёшь", "ёт", "ём", "ёте", {}, pres_note) append_pres_futr(forms, stem, nil, "у́", {}, {}, {}, {}, "у́т", pres_note) append_imper(forms, stem, nil, "и́", "и́те", pres_note) -- set prefix to "" as stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, com.make_ending_stressed(stem), nil, args, data, "no-pastml", pres_note) forms["past_m"] = nil for _, stressed_past_stem in ipairs(stressed_past_stems) do local pastm_stem, past_part_stem if stressed_past_stem == "е" then past_part_stem = com.make_ending_stressed(stem) pastm_stem = past_part_stem elseif stressed_past_stem == "ё" then past_part_stem = convert_last_e_to_yo(com.make_ending_stressed(stem)) pastm_stem = past_part_stem elseif stressed_past_stem == "ёе" then past_part_stem = com.make_ending_stressed(stem) pastm_stem = convert_last_e_to_yo(past_part_stem) else pastm_stem = stressed_past_stem past_part_stem = stressed_past_stem end local past_note = class_8b_stem_to_infinitive(pastm_stem) ~= full_inf and IRREG -- default for pres_pasv_part is blank; влечь -> влеко́мый handled through -- general override mechanism append_participles_2stem(forms, stem, nil, past_part_stem, nil, "у́щий", "-", "-", "ший", "ши", "-", pres_note, past_note) append_form(forms, "past_m", pastm_stem, nil, "", past_note) end -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) return forms end conjugations["9a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "еть") local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) local default_pres_stem = prefix .. rsub(base, "е", "") pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem .. "еть" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "ший", "ши", "ев") present_e_a(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и", "ите", pres_note) -- past_m doesn't end in л set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data, "no-pastml") set_ppp_from_past_m(forms, args, data) return forms end conjugations["9b"] = function(args, data) local forms = {} --for this type, it's important to distinguish impf and pf local impf = rfind(data.verb_type, "^impf") parse_variants(data, args[1], {"past", "+p", "*"}) local stem_noa = com.strip_ending(get_stressed_arg(args, 2), nil, "е́ть") local stem = rsub(stem_noa, "(.*)е", "%1ё") local pres_stem = get_opt_unstressed_arg(args, 3) -- stem used for past active and adverbial participles; defaults to past_m local past_part_stem = get_opt_stressed_arg(args, 4) no_stray_args(args, 4) local prefix, _, base, _ = split_monosyllabic_main_verb(stem, nil, "single_cons_base") local default_pres_stem = data.star and construct_long_prefix_variant(prefix) .. rsub(base, "[её]", "") or prefix .. rsub(base, "[её]", "") pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem_noa .. "е́ть" present_e_b(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и́", "и́те", pres_note) -- past_m doesn't end in л set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data, "no-pastml") set_ppp_from_past_m(forms, args, data) append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", {}, {}, -- impf: тереть -> тёрши -- pf: растереть -> растёрши, растере́в -- we handle (рас)тёрши down below because the stress depends on the -- past_m: запереть -> за́пер, за́перши(й) {}, {}, impf and {} or "е́в", pres_note) if past_part_stem then for _, ppstem in ipairs(rsplit(past_part_stem, ",")) do append_participles(forms, ppstem, nil, {}, {}, {}, "ший", "ши", {}) end else iterate_over_prop(forms, args, "past_m", function(ru, tr, note) append_participles(forms, ru, tr, {}, {}, {}, "ший", "ши", {}, note) end) end return forms end conjugations["10a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "оть") no_stray_args(args, 2) forms["infinitive"] = stem .. "оть" -- These verbs are perfective-only, no present participles append_participles(forms, stem, nil, "-", "-", "-", "овший", "овши", "ов") set_moving_ppp(forms, data) present_je(forms, stem, nil, "a") append_imper(forms, stem, nil, "и", "ите") set_past(forms, stem .. "ол", nil, "", "а", "о", "и") return forms end conjugations["10c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7"}) local inf_stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") -- present tense stressed stem "моло́ть" - ме́лет local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = com.make_ending_stressed(com.strip_ending(inf_stem, nil, "о́")) pres_stem = pres_stem or default_pres_stem -- remove accent for some forms local pres_stem_noa = com.remove_accents(pres_stem) local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = inf_stem .. "ть" -- default for pres_pasv_part is blank append_participles_2stem(forms, pres_stem, nil, inf_stem, nil, "ющий", "-", "я́", "вший", "вши", "в", pres_note) set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "c", nil, pres_note) append_imper(forms, pres_stem_noa, nil, "и́", "и́те", pres_note) set_past(forms, inf_stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["11a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ить") no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem .. "и") forms["infinitive"] = stem .. "ить" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "ивший", "ивши", "ив") present_je(forms, stem .. "ь", nil, "a") append_imper(forms, stem .. "ей", nil, "", "те") set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["11b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p", "*"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "и́ть") local pres_stem = get_opt_unstressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem .. "и́", nil, "single_cons_base") local default_pres_stem = data.star and construct_long_prefix_variant(prefix) .. rsub(base, "и́$", "") or stem pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem .. "и́ть" append_participles_2stem(forms, pres_stem, nil, stem, nil, "ью́щий", "-", "ья́", "и́вший", "и́вши", "и́в", pres_note) present_je(forms, pres_stem .. "ь", nil, "b", nil, pres_note) append_imper(forms, stem .. "е́й", nil, "", "те") -- e.g. пила́, лила́ set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["12a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = stem pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" append_participles_2stem(forms, pres_stem, nil, stem, nil, "ющий", "емый", "я", "вший", "вши", "в", pres_note) present_je(forms, pres_stem, nil, "a", nil, pres_note) append_imper(forms, pres_stem .. "й", nil, "", "те", pres_note) set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["12b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_opt_unstressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = com.make_unstressed_once(stem) pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "ю́щий", "-", "я́", "вший", "вши", "в", pres_note) present_je(forms, pres_stem, nil, "b", nil, pres_note) -- the preceding vowel is stressed append_imper(forms, pres_stem .. "́й", nil, "", "те", pres_note) -- e.g. гнила́ but пе́ла set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["13b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = com.strip_ending(stem, nil, "ва́") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- tricky to use append_participles_2stem() because only pres_actv_part -- uses pres_stem, not all present participles forms["pres_actv_part"] = pres_stem .. "ю́щий" forms["pres_pasv_part"] = stem .. "емый" forms["pres_adv_part"] = stem .. "я" forms["past_actv_part"] = stem .. "вший" forms["past_adv_part"] = stem .. "вши" forms["past_adv_part_short"] = stem .. "в" set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "b") forms["impr_sg"] = stem .. "й" forms["impr_pl"] = stem .. "йте" set_past(forms, stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["14a"] = function(args, data) -- only one verb: вы́жать local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_stressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "вший", "вши", "в") present_e_a(forms, pres_stem) forms["impr_sg"] = pres_stem .. "и" forms["impr_pl"] = pres_stem .. "ите" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["14b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_unstressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_b(forms, pres_stem) forms["impr_sg"] = pres_stem .. "и́" forms["impr_pl"] = pres_stem .. "и́те" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["14c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_stressed_arg(args, 3) local pres_stem_noa = com.make_unstressed(pres_stem) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_c(forms, pres_stem) forms["impr_sg"] = pres_stem_noa .. "и́" forms["impr_pl"] = pres_stem_noa .. "и́те" --two forms for past_m: при́нялся, приня́лся --изъя́ла but приняла́ set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["15a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, stem, nil, "нущий", "-", "-", "вший", "вши", "в") present_e_a(forms, stem .. "н") forms["impr_sg"] = stem .. "нь" forms["impr_pl"] = stem .. "ньте" set_past(forms, stem .. "л", nil, "", "а", "о", "и") set_ppp_from_past_m(forms, args, data) return forms end conjugations["16a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, stem, nil, "ву́щий", "-", "-", "вший", "вши", "в") present_e_a(forms, stem .. "в") forms["impr_sg"] = stem .. "ви" forms["impr_pl"] = stem .. "вите" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["16b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local stem_noa = com.make_unstressed(stem) no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles(forms, stem, nil, "ву́щий", "-", "вя́", "вший", "вши", "в") present_e_b(forms, stem_noa .. "в") forms["impr_sg"] = stem_noa .. "ви́" forms["impr_pl"] = stem_noa .. "ви́те" -- e.g. прижило́сь, прижи́лось set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg"] = function(args, data) local main = select(3, split_known_main_verb(get_stressed_arg(args, 2), -- честь must go before есть {"бежа́ть", "бѣжа́ть", "хоте́ть", "хотѣ́ть", "да́ть", "че́сть", "е́сть", "ѣ́сть", "сы́пать", "лга́ть", "мо́чь", "идти́", "йти́", "е́хать", "ѣ́хать", "мину́ть", "живописа́ть", "ле́чь", "зи́ждить", "зы́бить", "кля́сть", "стели́ть", "бы́ть", "сса́ть", "сца́ть", "чти́ть", "шиби́ть", "реве́ть", "има́ть", "вня́ть", "обя́зывать"})) main = com.make_unstressed_once(main) if not conjugations["irreg-" .. main] then error("Strange, can't find conjugation for main verb " .. main) end return conjugations["irreg-" .. main](args, data) end conjugations["irreg-бежать"] = function(args, data) -- irregular, only for verbs derived from бежать with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"бежа́ть", "бѣжа́ть"}) data.title = com.is_stressed(prefix) and "5a" or "5b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "бежа́ть" append_participles_2stem(forms, "бег", nil, "бежа́", nil, "у́щий", "-", "-", "вший", "вши", "в", IRREG) append_imper(forms, "беги́", nil, "", "те", IRREG) append_pres_futr(forms, "бе", nil, "гу́" .. IRREG, "жи́шь", "жи́т", "жи́м", "жи́те", "гу́т" .. IRREG) set_past(forms, "бежа́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^бе", "бѣ") end prepend_prefix(forms, prefix) -- no PPP's for any derivatives of бежать return forms end conjugations["irreg-бѣжать"] = conjugations["irreg-бежать"] conjugations["irreg-хотеть"] = function(args, data) -- irregular, only for verbs derived from хотеть with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"хоте́ть", "хотѣ́ть"}) data.title = "5c'" data.cat_conj_types = {"5c"} -- no class for 5c', no point in creating for just this verb -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "хоте́ть" append_participles_2stem(forms, "хот", nil, "хоте́", nil, "я́щий", "-", "я́", "вший", "вши", "в") append_imper(forms, "хоти́", nil, "", "те") append_pres_futr(forms, "", nil, "хочу́", "хо́чешь" .. IRREG, "хо́чет" .. IRREG, "хоти́м", "хоти́те", "хотя́т") set_past(forms, "хоте́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^хоте", "хотѣ") end prepend_prefix(forms, prefix) return forms end conjugations["irreg-хотѣть"] = conjugations["irreg-хотеть"] conjugations["irreg-дать"] = function(args, data) -- irregular, only for verbs derived from дать with the same stress pattern and вы́дать local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "да́ть") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "да́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "", nil, "даю́щий", "-", "-", "да́вший", "да́вши", "да́в") append_imper(forms, "да́й", nil, "", "те") append_pres_futr(forms, "", nil, "да́м", "да́шь", "да́ст", "дади́м", "дади́те", "даду́т") prepend_prefix(forms, prefix) set_past_by_stress(forms, data.past_stress, prefix, nil, "да́", nil, args, data) if data.ppp then if prefix == "пере" then set_ppp(forms, "", nil, "пе́реданный") elseif prefix == "раз" then set_ppp(forms, "", nil, "ро́зданный") else set_moving_ppp(forms, data) end end return forms end conjugations["irreg-есть"] = function(args, data) -- irregular, only for verbs derived from есть local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"е́сть", "ѣ́сть"}) data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "е́сть" append_participles_2stem(forms, "ед", nil, "е́", nil, "я́щий", "о́мый", "я́", "вший", "вши", "в") if data.ppp then set_ppp(forms, "е́д", nil, "енный") end append_imper(forms, "е́шь", nil, "", "те") append_pres_futr(forms, "е́", nil, "м", "шь", "ст", "ди́м", "ди́те", "дя́т") set_past(forms, "е́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^е", "ѣ") end prepend_prefix(forms, prefix) return forms end conjugations["irreg-ѣсть"] = conjugations["irreg-есть"] conjugations["irreg-сыпать"] = function(args, data) -- irregular, only for verbs derived from сыпать local forms = {} --for this type, it's important to distinguish if it's reflexive for вы́сыпаться vs. вы́сыпать imperative local prefix = split_known_main_verb(get_stressed_arg(args, 2), "сы́пать") data.title = "6a" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "сы́пать" append_participles(forms, "сы́п", nil, "лющий", "лемый", {"ля", "я" .. IRREG}, "авший", "авши", "ав") append_imper(forms, "сы́п", nil, -- вы́сыпать (but not вы́сыпаться) has two imperative singulars com.is_stressed(prefix) and not data.refl and {"и", "ь"} or "ь", "ьте", IRREG) present_je(forms, "сы́пл", nil, "a") append_pres_futr(forms, "сы́п", nil, {}, "ешь", "ет", "ем", "ете", {}, IRREG) set_past(forms, "сы́пал", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-лгать"] = function(args, data) -- irregular, only for verbs derived from лгать with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "лга́ть") data.title = "6°b/c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "лга́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "лг", nil, "у́щий", "-", "-", "а́вший", "а́вши", "а́в") append_imper(forms, "лги́", nil, "", "те") append_pres_futr(forms, "", nil, "лгу́", "лжёшь" .. IRREG, "лжёт" .. IRREG, "лжём" .. IRREG, "лжёте" .. IRREG, "лгу́т") set_past(forms, "лга́л", nil, "", "а́", "о", "и") prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-мочь"] = function(args, data) -- irregular, only for verbs derived from мочь with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "мо́чь") data.title = "8c/b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "мо́чь" -- no passive or adverbial participles append_participles(forms, "мо́г", nil, "у́щий", "-", "-", "ший", "-", "-") append_imper(forms, "моги́", nil, "", "те") append_pres_futr(forms, "", nil, "могу́", "мо́жешь", "мо́жет", "мо́жем", "мо́жете", "мо́гут") set_past(forms, "мо́г", nil, "", "ла́", "ло́", "ли́") prepend_prefix(forms, prefix) return forms end conjugations["irreg-идти"] = function(args, data) -- irregular, only for verbs derived from идти, including прийти́ and в́ыйти local forms = {} local prefix = args[2] == "идти́" and "" or split_known_main_verb(get_stressed_arg(args, 2), "йти́") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b/b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no pres_pasv_part if prefix == "" then -- only идти, present imperfective forms["infinitive"] = "идти́" append_imper(forms, "иди́", nil, "", "те") present_e_b(forms, "ид") -- no past_adv_part_short append_participles(forms, "", nil, "иду́щий", "-", "идя́", "ше́дший", "ше́дши", "-") elseif rfind(prefix, "и$") then -- при forms["infinitive"] = "йти́" append_imper(forms, "ди́", nil, "", "те") present_e_b(forms, "д") append_participles(forms, "", nil, "-", "-", "-", "ше́дший", "ше́дши", "дя́") else forms["infinitive"] = "йти́" append_imper(forms, "йди́", nil, "", "те") present_e_b(forms, "йд") append_participles(forms, "", nil, "-", "-", "-", "ше́дший", "ше́дши", "йдя́") end set_past(forms, "", nil, "шёл", "шла́", "шло́", "шли́") prepend_prefix(forms, prefix) if data.ppp then if prefix == "на" or prefix == "про" then -- найти́ and пройти́ exceptionally have the stress on the prefix set_ppp(forms, prefix, nil, "́йденный") else -- вы́йти and прийти́ are intransitive so we don't have to worry about them set_ppp(forms, prefix, nil, "йдённый") end end return forms end conjugations["irreg-йти"] = conjugations["irreg-идти"] conjugations["irreg-ехать"] = function(args, data) -- irregular, only for verbs derived from ехать local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"е́хать", "ѣ́хать"}) data.title = "irreg-a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "е́хать" -- no pres_pasv_part -- no pres_adv_part append_participles_2stem(forms, "е́д", nil, "е́х", nil, "ущий", "-", "-", "авший", "авши", "ав") present_e_a(forms, "е́д") set_past(forms, "е́хал", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^е", "ѣ") end prepend_prefix(forms, prefix) --special-case the imperative --literary (special) imperative forms for ехать are поезжа́й, поезжа́йте local impstem = data.old and "ѣзжа́й" or "езжа́й" if prefix == "" then append_imper(forms, "по" .. impstem, nil, "", "те") append_imper(forms, impstem, nil, "", "те") elseif com.is_stressed(prefix) then append_imper(forms, com.make_unstressed_once(prefix) .. impstem, nil, "", "те") else append_imper(forms, prefix .. impstem, nil, "", "те") end return forms end conjugations["irreg-ѣхать"] = conjugations["irreg-ехать"] conjugations["irreg-минуть"] = function(args, data) -- for the irregular verb "мину́ть" local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "мину́ть") data.title = "3c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "мину́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "ми́н", nil, "у́щий", "-", "-", "у́вший", "у́вши", "у́в") present_e_c(forms, "ми́н") forms["pres_futr_1sg"] = "-" -- no futr 1sg -- no imperative -- two possible variants, one with root-only stress, the other with -- either root or suffix stress. if not args["root_past_stress"] then append_past(forms, "мину́л", nil, "", "а", "о", "и") end append_past(forms, "ми́нул", nil, "", "а", "о", "и", IRREG) prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-живописать"] = function(args, data) -- for irregular verb "живописа́ть", mixture of types 1 and 2 local forms = {} local inf = get_stressed_arg(args, 2) data.title = "1a" parse_variants(data, args[1], {"+p"}) local inf_stem = com.strip_ending(inf, nil, "ть") local pres_stem = rfind(inf_stem, "а́$") and rsub(inf_stem, "а́$", "у́") or error("Unexpected infinitive " .. inf) no_stray_args(args, 2) forms["infinitive"] = inf_stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, inf_stem, nil, "ющий", "-", "я", "вший", "вши", "в", IRREG) set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "a", nil, IRREG) append_imper(forms, pres_stem .. "й", nil, "", "те", IRREG) set_past(forms, inf_stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["irreg-лечь"] = function(args, data) -- irregular, only for verbs derived from лечь with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "ле́чь") data.title = "8a/b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "ле́чь" -- no pres parts because always perfective -- no past_adv_part_short append_participles(forms, "лёг", nil, "-", "-", "-", "ший", "ши", "-") append_imper(forms, "ля́г", nil, "", "те", IRREG) append_pres_futr(forms, "ля́", nil, "гу", "жешь", "жет", "жем", "жете", "гут", IRREG) set_past(forms, "", nil, "лёг", "легла́", "легло́", "легли́") prepend_prefix(forms, prefix) return forms end conjugations["irreg-честь"] = function(args, data) -- irregular, only for verbs derived from идти, including прийти́ and в́ыйти local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "че́сть") local pre_two_cons_prefix = prefix == "об" and "обо" or prefix == "с" and "со" or prefix == "рас" and "разо" or prefix data.title = prefix == "" and "7b/b" or com.is_stressed(prefix) and "7a⑨" or pre_two_cons_prefix ~= prefix and "7*b/b⑨" or "7b/b⑨" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no pres_pasv_part forms["infinitive"] = "че́сть" append_imper(forms, "чти́", nil, "", "те", IRREG) present_e_b(forms, "чт", nil, IRREG) if prefix == "" then append_participles(forms, "", nil, "чту́щий", "-", "чтя́", "чти́вший", "чти́вши", "чти́в", IRREG) elseif com.is_stressed(prefix) then append_participles(forms, "", nil, "-", "-", "-", "-", "чтя́", "-", IRREG) else append_participles(forms, "", nil, "-", "-", "-", "-", {"чтя́" .. IRREG, "чётши*"}, "-") m_table.insertIfNot(data.internal_notes, "* Dated.") end if data.ppp then set_ppp(forms, "", nil, "чтённый" .. IRREG) end set_past(forms, "", nil, "чёл", "чла́" .. IRREG, "чло́" .. IRREG, "чли́" .. IRREG) prepend_prefix(forms, prefix, pre_two_cons_prefix) return forms end conjugations["irreg-зиждить"] = function(args, data) -- irregular, only for verbs derived from зиждить(ся) with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "зи́ждить") data.title = "irreg-a" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "зи́ждить" append_participles(forms, "зи́жд", nil, "ущий", "емый", "я", "ивший", "ивши", "ив") if data.ppp then set_ppp(forms, "зи́жд", nil, "енный") end append_imper(forms, "зи́жди", nil, "", "те") present_e_a(forms, "зи́жд") set_past(forms, "зи́ждил", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-зыбить"] = function(args, data) -- irregular, only for verbs derived from зыбить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "зы́бить") data.title = "irreg-a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "зы́бить" append_participles(forms, "зы́б", nil, "лющий", "лемый", "ля", "ивший", "ивши", "ив") append_imper(forms, "зы́бли", nil, "", "те") present_je(forms, "зы́б", nil, "a") set_past(forms, "зы́бил", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-клясть"] = function(args, data) -- irregular, only for verbs derived from клясть with the same stress pattern local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "кля́сть") data.title = "irreg-b" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "кля́сть" append_participles_2stem(forms, "клян", nil, "кля́", nil, "у́щий", "и́мый", "я́", "вший", "вши", "в") append_imper(forms, "кляни́", nil, "", "те") present_e_b(forms, "клян") prepend_prefix(forms, prefix) set_past_by_stress(forms, data.past_stress, prefix, nil, "кля́", nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg-стелить"] = function(args, data) -- irregular, only for verbs derived from стелить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "стели́ть") data.title = com.is_stressed(prefix) and "4a" or "4c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "стели́ть" append_participles(forms, "сте́л", nil, "ющий" .. IRREG, "и́мый", "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, "сте́л", nil, data.title) append_imper(forms, "стели́", nil, "", "те") append_pres_futr(forms, "сте́л", nil, "ю́", {}, {}, {}, {}, {}) append_pres_futr(forms, "сте́л", nil, {}, "ешь", "ет", "ем", "ете", "ют", IRREG) set_past(forms, "стели́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-быть"] = function(args, data) -- irregular, only for verbs derived from быть with various stress patterns, the actual verb быть different from its derivatives local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "бы́ть") data.title = "irreg-a" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "бы́ть" -- no pres_pasv_part append_participles(forms, "", nil, "су́щий", "-", "бу́дучи", "бы́вший", "бы́вши", "бы́в") append_imper(forms, "бу́дь", nil, "", "те") prepend_prefix(forms, prefix) -- only for "бы́ть", some forms are archaic if forms["infinitive"] == "бы́ть" then append_pres_futr(forms, "", nil, "есть", "есть", "есть", "есть", "есть", "есть") elseif com.is_stressed(prefix) then -- if the prefix is stressed, e.g. "вы́быть" present_e_a(forms, prefix .. "буд") else present_e_a(forms, prefix .. "бу́д") end set_past_by_stress(forms, data.past_stress, prefix, nil, "бы́", nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg-ссать-сцать"] = function(args, data) -- irregular, only for verbs derived from ссать and сцать (both vulgar!) local forms = {} local prefix, _, stem = split_known_main_verb(get_stressed_arg(args, 2), {"сса́ть", "сца́ть"}) data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) stem = com.strip_ending(stem, nil, "ть") local pres_stem = rsub(stem, "а́?$", "") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, pres_stem, nil, "у́щий", "-", "-", "а́вший", "а́вши", "а́в") append_imper(forms, pres_stem, nil, "ы́", "ы́те") append_pres_futr(forms, pres_stem, nil, "у́", "ы́шь", "ы́т", "ы́м", "ы́те", "у́т") set_past(forms, stem .. "л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-ссать"] = conjugations["irreg-ссать-сцать"] conjugations["irreg-сцать"] = conjugations["irreg-ссать-сцать"] conjugations["irreg-чтить"] = function(args, data) -- irregular, only for verbs derived from чтить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "чти́ть") data.title = "4b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "чти́ть" append_participles_2stem(forms, "чт", nil, "чти́", nil, {"я́щий", "у́щий" .. IRREG}, "и́мый", "я́", "вший", "вши", "в") if data.ppp then set_ppp(forms, "чт", nil, "ённый") end append_imper(forms, "чти́", nil, "", "те") append_pres_futr(forms, "чт", nil, "у́" .. IRREG, "и́шь", "и́т", "и́м", "и́те", {"я́т", "у́т" .. IRREG}) set_past(forms, "чти́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-шибить"] = function(args, data) -- irregular, only for verbs in -шибить(ся) local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "шиби́ть") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no present participles forms["infinitive"] = "шиби́ть" append_participles(forms, "шиби́", nil, "-", "-", "-", "вший", "вши", "в") if data.ppp then set_ppp(forms, "ши́бл", nil, "енный") end append_imper(forms, "шиби́", nil, "", "те") present_e_b(forms, "шиб") set_past(forms, "ши́б", nil, "", "ла", "ло", "ли") prepend_prefix(forms, prefix) return forms end conjugations["irreg-реветь"] = function(args, data) -- irregular, only for verbs derived from "реветь" local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "реве́ть") data.title = "irreg-b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "реве́ть" -- no pres_pasv_part append_participles_2stem(forms, "рев", nil, "реве́", nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_b(forms, "рев") append_imper(forms, "реви́", nil, "", "те") set_past(forms, "реве́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-имать"] = function(args, data) -- irregular, only for внимать and certain archaic verbs (e.g. имать as -- conjugated in the 18th century, отъимать) local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "има́ть") data.title = "1a // 6a" data.cat_conj_types = {"1a", "6a"} parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "има́ть" -- handle внемл- forms append_participles(forms, "е́мл", nil, "ющий", "емый", {"я", "я́"}, {}, {}, {}) -- handle внима́- forms append_participles(forms, "има́", nil, "ющий", "емый", "я", "вший", "вши", "в") if data.ppp then -- FIXME, do class-1a-type ppp's (e.g. вни́манный) exist? -- ruwikt marks them with a * set_ppp(forms, "е́мл", nil, "енный") end append_imper(forms, "", nil, {"е́мли", "емли́", "има́й"}, {"е́млите", "емли́те", "има́йте"}) present_je(forms, "е́мл", nil, "a") -- Both вне́млю and внемлю́ are possible append_pres_futr(forms, "емл", nil, "ю́", {}, {}, {}, {}, {}) present_je(forms, "има́", nil, "a") set_past(forms, "има́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-внять"] = function(args, data) -- irregular, only for внять local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "вня́ть") data.title = "14c/c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "вня́ть" -- perfective only; no present participles append_participles(forms, "вня́", nil, "-", "-", "-", "вший", "вши", "в") append_imper(forms, "вними́", nil, "", "те") append_imper(forms, "вонми́", nil, "", "те") present_e_c(forms, "вни́м") present_e_c(forms, "во́нм") set_past(forms, "вня́л", nil, "", "а́", "о", "и") set_ppp_from_past_m(forms, args, data) prepend_prefix(forms, prefix) return forms end conjugations["irreg-обязывать"] = function(args, data) -- irregular, only for обязывать and обязываться local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "обя́зывать") data.title = "1a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "обя́зывать" append_participles_2stem(forms, "обя́з", nil, "обя́зыва", nil, {"ывающий", "у́ющий"}, {"ываемый", "у́емый"}, {"ывая", "у́я"}, "вший", "вши", "в") append_imper(forms, "обя́зывай", nil, "", "те") append_imper(forms, "обязу́й", nil, "", "те") present_je(forms, "обя́зыва", nil, "a") present_je(forms, "обязу́", nil, "a") set_past(forms, "обя́зывал", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end --[=[ Partial conjugation functions ]=] -- Present forms with -e-, no j-vowels. present_e_a = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у", "ешь", "ет", "ем", "ете", "ут", note) end present_e_b = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у́", "ёшь", "ёт", "ём", "ёте", "у́т", note) end present_e_c = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у́", "ешь", "ет", "ем", "ете", "ут", note) end -- Present forms with -e- and iotated stem. ABC = "a", "b" or "c", indicating -- the accent pattern. If SHCH is set, iotate final т as щ, not ч. If NOTE -- is given, add it to each form. present_je = function(forms, stem, tr, abc, shch, note) local iotated_stem, iotated_tr = com.iotation(stem, tr, shch) assert(abc == "a" or abc == "b" or abc == "c") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") -- or no_iotation local ending_1sg = hushing and (abc == "a" and "у" or "у́") or not hushing and (abc == "a" and "ю" or "ю́") if abc == "b" then append_pres_futr(forms, iotated_stem, iotated_tr, {}, "ёшь", "ёт", "ём", "ёте", (hushing and "у́т" or "ю́т"), note) else append_pres_futr(forms, iotated_stem, iotated_tr, {}, "ешь", "ет", "ем", "ете", (hushing and "ут" or "ют"), note) end append_pres_futr(forms, iotated_stem, iotated_tr, ending_1sg, {}, {}, {}, {}, {}, note) end -- Present forms with -i- (and iotated stem in the 1sg). ABC = "a", "b" or "c", -- indicating the accent pattern. If SHCH is set, iotate final т as щ, not ч. -- If NOTE is given, add it to each form. present_i = function(forms, stem, tr, abc, shch, note) local iotated_stem, iotated_tr = com.iotation(stem, tr, shch) assert(abc == "a" or abc == "b" or abc == "c") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local iotated_hushing = rfind(iotated_stem, "[шщжч]$") local hushing = rfind(stem, "[шщжч]$") local ending_1sg = iotated_hushing and (abc == "a" and "у" or "у́") or not iotated_hushing and (abc == "a" and "ю" or "ю́") if abc == "b" then append_pres_futr(forms, stem, tr, {}, "и́шь", "и́т", "и́м", "и́те", hushing and "а́т" or "я́т", note) else append_pres_futr(forms, stem, tr, {}, "ишь", "ит", "им", "ите", hushing and "ат" or "ят", note) end append_pres_futr(forms, iotated_stem, iotated_tr, ending_1sg, {}, {}, {}, {}, {}, note) end -- Add the reflexive particle to all verb forms make_reflexive = function(forms, reflex_stress) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) end if is_vowel_stem(ruentry) then forms[key] = {ruentry .. "сь" .. runotes, trentry and trentry .. "sʹ" .. trnotes} -- if a past_m form doesn't contain a stress, add a stressed -- particle "ся́" if called for elseif reflex_stress and com.is_unstressed(ruentry) and rfind(key, "^past_m") then forms[key] = {ruentry .. "ся́" .. runotes, trentry and trentry .. "sja" .. AC .. trnotes} else forms[key] = {ruentry .. "ся" .. runotes, trentry and trentry .. "sja" .. trnotes} end end end end -- Convert verb forms to pre-reform style by adding ъ to consonant-final -- forms (excluding those ending in й and ь) and converting -ий to -ій and -- -ийся to -ійся make_pre_reform = function(forms) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) if rfind(ruentry, "[бцдфгчклмнпрствшхзжщ]$") then forms[key] = {ruentry .. "ъ" .. runotes, tr} else forms[key] = {rsub(rsub(ruentry, "ий$", "ій"), "ийся$", "ійся") .. runotes, tr} end end end end local function setup_pres_futr(forms, perf, old) -- Copy the main form FROMFORM to the main form TOFORM, and copy all -- associated alternative forms. local function copy_form(fromform, toform) local fromforms = main_to_all_verb_forms[fromform] local toforms = main_to_all_verb_forms[toform] local numforms = #fromforms assert(#toforms == numforms) for i=1,numforms do forms[toforms[i]] = forms[fromforms[i]] end end -- Copy pres_futr_* to pres_* (imperfective) or futr_* (perfective). if perf then copy_form("pres_futr_1sg", "futr_1sg") copy_form("pres_futr_2sg", "futr_2sg") copy_form("pres_futr_3sg", "futr_3sg") copy_form("pres_futr_1pl", "futr_1pl") copy_form("pres_futr_2pl", "futr_2pl") copy_form("pres_futr_3pl", "futr_3pl") else copy_form("pres_futr_1sg", "pres_1sg") copy_form("pres_futr_2sg", "pres_2sg") copy_form("pres_futr_3sg", "pres_3sg") copy_form("pres_futr_1pl", "pres_1pl") copy_form("pres_futr_2pl", "pres_2pl") copy_form("pres_futr_3pl", "pres_3pl") end local futr_data = { {"futr_1sg", "бу́ду", "búdu"}, {"futr_2sg", "бу́дешь", "búdešʹ"}, {"futr_3sg", "бу́дет" .. (old and "ъ" or ""), "búdet"}, {"futr_1pl", "бу́дем" .. (old and "ъ" or ""), "búdem"}, {"futr_2pl", "бу́дете", "búdete"}, {"futr_3pl", "бу́дут" .. (old and "ъ" or ""), "búdut"} } local function insert_future(inf, inf_tr) for _, fut in ipairs(futr_data) do append_to_arg_chain(forms, fut[1], fut[1], {fut[2] .. inf, inf_tr and fut[3] .. inf_tr}) end end -- Insert future, if required (there may conceivably be multiple infitives). for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local infinitive = forms[form] if infinitive then local inf, inf_tr = extract_russian_tr(forms[form]) -- only for "бы́ть" the future forms are бу́ду, бу́дешь, etc. if inf == "бы́ть" then insert_future("", nil) elseif not perf then insert_future(" " .. inf, inf_tr and " " .. inf_tr) end end end end parse_and_stress_override = function(form, val, existing, all_existing) if rfind(form, "^pres_futr") then error("Overrides of pres_futr* are illegal, use pres_* or futr_*") end local allow_unaccented val, allow_unaccented = rsubb(val, "^%*", "") local ru, tr = com.split_russian_tr(val) -- past_m can be unaccented in connection with reflex_stress=ся́ if not allow_unaccented and not rfind(form, "^past_m") then if tr and com.is_unstressed(ru) ~= com.is_unstressed(tr) then error("Override " .. form .. "=" .. ru .. " and translit " .. tr .. " must have same accent pattern") end if com.is_monosyllabic(ru) then ru, tr = com.make_ending_stressed(ru, tr) elseif com.needs_accents(ru) then error("Override " .. form .. "=" .. ru .. " requires an accent") end end if rfind(ru, "%+") then -- If either the existing or override has manual translit, the resulting -- form should have manual translit. We specify ALWAYS_TRANSLIT if -- the override has manual translit, so that we can substitute the -- existing translit into the override translit. local existing_ru, existing_tr = extract_russian_tr(existing, not not tr) -- used especially for present participles; substitute existing form, -- minus any "awkward-" or "none-" prefixes. ru = rsub(ru, "%+", strip_arg_status_prefix(existing_ru)) -- If there's existing translit but not in the override, make sure it's -- carried along. if existing_tr and not tr then tr = com.translit(ru) end tr = tr and rsub(tr, "%+", strip_arg_status_prefix(existing_tr)) end -- If there's an override and it doesn't match an existing form, it's -- irregular and indicate it using the IRREG marker. We don't do this if -- the override simply removes a form. We do do this if there aren't any -- existing forms, on the theory that the presence of a form when none is -- normally called for is an irregularity. When comparing against the -- existing forms, strip any status prefix (e.g. 'awkward-'). if all_existing then local all_existing_stripped = {} for _, ae in ipairs(all_existing) do local existing_ru, existing_tr = extract_russian_tr(ae) existing_ru = strip_arg_status_prefix(existing_ru) existing_tr = existing_tr and strip_arg_status_prefix(existing_tr) table.insert(all_existing_stripped, {existing_ru, existing_tr}) end if ru ~= "-" and not contains_form(all_existing_stripped, {ru, tr}) then ru = ru .. IRREG tr = tr and tr .. IRREG end end return {ru, tr} end -- Set up pres_* or futr_*; handle *sym/*tail/*tailall notes and overrides. handle_forms_and_overrides = function(args, forms, data) setup_pres_futr(forms, data.perf, data.old) --handle overrides (formerly we only had past_pasv_part as a --general override, plus scattered main-form overrides in particular --conjugation classes) for _, all_forms in pairs(main_to_all_verb_forms) do local i = 0 local orig_forms = {} for _, form in ipairs(all_forms) do if forms[form] then table.insert(orig_forms, forms[form]) end end for _, form in ipairs(all_forms) do i = i + 1 -- If we auto-generated the past passive participle in order to -- check for irregular overrides, make sure to erase any such -- participles that weren't overridden. This happens for example -- in обнять, where there are two automatically generated past -- passive participles but a single ppp=о́внятый override. local override = args[form] or ( data.ppp_auto_generated and rfind(form, "^past_pasv_part") and "-" ) if override then forms[form] = parse_and_stress_override(form, override, forms[form], orig_forms) elseif i == 1 then forms[form] = forms[form] or "" end end end local function append_value(forms, prop, value) if forms[prop] and forms[prop] ~= "" and forms[prop] ~= "-" then value = com.split_russian_tr(value, "dopair") local curval = forms[prop] if type(curval) == "string" then curval = {curval} end forms[prop] = com.concat_paired_russian_tr(curval, value) end end local function append_note_all(forms, proplist, value) for _, prop in ipairs(proplist) do append_value(forms, prop, value) end end local function append_note_last(forms, proplist, value, gt_one) local numprops = 0 local lastprop -- Find the last property in the series with a value for _, prop in ipairs(proplist) do if forms[prop] and forms[prop] ~= "" and forms[prop] ~= "-" then numprops = numprops + 1 lastprop = prop end end if numprops > (gt_one and 1 or 0) then append_value(forms, lastprop, value) end end for _, proplist in ipairs(all_verb_forms) do -- Handle PROP_sym, which applies to all overridable properties, including -- alternative forms, and applies to exactly that property. for _, prop in ipairs(proplist) do if args[prop .. "_sym"] then append_value(forms, prop, args[prop .. "_sym"]) end end local propname = proplist[1] -- Handle PROP_tail, which applies to a series of properties (e.g. past_m, -- past_m2, ...) and appends to the last one. if args[propname .. "_tail"] then append_note_last(forms, proplist, args[propname .. "_tail"]) end -- Handle PROP_tailall, which applies to a series of properties and -- appends to all. if args[propname .. "_tailall"] then append_note_all(forms, proplist, args[propname .. "_tailall"]) end end -- Now handle pasttail, pasttailall, prestail, prestailall, etc. -- Table listing tail-arg prefix and corresponding verb forms. local tailargs = { {"past", past_verb_forms}, {"pres", pres_verb_forms}, {"futr", futr_verb_forms}, {"impr", impr_verb_forms}, {"part", part_verb_forms}, {"prespart", pres_part_verb_forms}, {"pastpart", past_part_verb_forms}, {"", all_main_verb_forms} } for _, tailspec in ipairs(tailargs) do local tailforms = tailspec[2] -- Handle the ...tail variants. local tailarg = tailspec[1] .. "tail" if args[tailarg] then track(tailarg) for _, prop in ipairs(tailforms) do append_note_last(forms, main_to_all_verb_forms[prop], args[tailarg], ">1") end end -- Handle the ...tailall variants. local tailallarg = tailspec[1] .. "tailall" if args[tailallarg] then track(tailallarg) for _, prop in ipairs(tailforms) do append_note_all(forms, main_to_all_verb_forms[prop], args[tailallarg]) end end end end -- Finish generating the forms; primarily, clear out unused forms. finish_generating_forms = function(forms, data) -- Convert any main form that's nil (meaning no forms at all corresponding -- to this main form) to the empty string. for main_form, _ in pairs(main_to_all_verb_forms) do if not forms[main_form] then forms[main_form] = "" end end -- Set the main form FORM to the empty string, and corresponding alt forms -- to nil. local function clear_form(form) local i = 0 for _, altform in ipairs(main_to_all_verb_forms[form]) do i = i + 1 if i == 1 then forms[altform] = "" else forms[altform] = nil end end end -- Intransitive and reflexive verbs have no passive participles -- (unless has_prpp=y and/or has_ppp=y). if data.intr or data.refl then if not data.has_prpp then clear_form("pres_pasv_part") end if not data.has_ppp then clear_form("past_pasv_part") end end if data.refl then -- no past_adv_part_short for reflexive verbs clear_form("past_adv_part_short") end -- Impersonal verbs normally have no passive participles, but allow them -- if there's specifically an override. We only do this for the present -- passive participle because the past passive participle isn't inserted -- by default, and we still want +p to work, which doesn't currently set -- data.ppp_override. if data.impers and not data.prpp_override then clear_form("pres_pasv_part") end if data.impers then clear_form("pres_1sg") clear_form("pres_2sg") clear_form("pres_1pl") clear_form("pres_2pl") clear_form("pres_3pl") clear_form("futr_1sg") clear_form("futr_2sg") clear_form("futr_1pl") clear_form("futr_2pl") clear_form("futr_3pl") clear_form("past_m") clear_form("past_f") clear_form("past_pl") clear_form("past_m_short") clear_form("past_f_short") clear_form("past_pl_short") clear_form("pres_actv_part") clear_form("past_actv_part") clear_form("pres_adv_part") clear_form("past_adv_part") clear_form("past_adv_part_short") clear_form("impr_sg") clear_form("impr_pl") end -- Perfective and iterative verbs have no present forms, as well as -- verbs marked nopres=1. if data.perf or data.iter or data.nopres then clear_form("pres_actv_part") clear_form("pres_pasv_part") clear_form("pres_adv_part") clear_form("pres_1sg") clear_form("pres_2sg") clear_form("pres_3sg") clear_form("pres_1pl") clear_form("pres_2pl") clear_form("pres_3pl") end -- Some verbs (e.g. грясти́, густи́) have no past if data.nopast then clear_form("past_m") clear_form("past_f") clear_form("past_n") clear_form("past_pl") clear_form("past_m_short") clear_form("past_f_short") clear_form("past_n_short") clear_form("past_pl_short") clear_form("past_actv_part") clear_form("past_pasv_part") clear_form("past_adv_part") clear_form("past_adv_part_short") end -- Iterative verbs and verbs marked noimpr=1 have no imperative forms. if data.iter or data.noimpr then clear_form("impr_sg") clear_form("impr_pl") end -- Iterative verbs and verbs marked nofutr=1 have no future forms. if data.iter or data.nofutr then clear_form("futr_1sg") clear_form("futr_2sg") clear_form("futr_3sg") clear_form("futr_1pl") clear_form("futr_2pl") clear_form("futr_3pl") end --handle "none-" and "awkward-" prefixes (used especially for pres_pasv_part) local footnote_sym = nil for _, all_forms in pairs(main_to_all_verb_forms) do local i = 0 for _, form in ipairs(all_forms) do i = i + 1 if forms[form] then local formru, formtr = extract_russian_tr(forms[form]) if rfind(formru, "^none%-") then if i == 1 then forms[form] = "" else forms[form] = nil end elseif rfind(formru, "^awkward%-") then if not footnote_sym then footnote_sym = next_note_symbol(data) m_table.insertIfNot(data.internal_notes, footnote_sym .. " Rare and awkward.") end forms[form] = {rsub(formru, "^awkward%-", "") .. footnote_sym, formtr and rsub(formtr, "^awkward%-", "") .. footnote_sym} end end end end --Insert footnote for IRREG symbol if present. for _, all_forms in pairs(main_to_all_verb_forms) do for _, form in ipairs(all_forms) do if forms[form] then local formru = extract_russian_tr(forms[form]) if rfind(formru, IRREG) then m_table.insertIfNot(data.internal_notes, IRREG .. " Irregular.") end end end end end local accel_forms = { -- present tense pres_1sg = "1|s|pres|ind", pres_2sg = "2|s|pres|ind", pres_3sg = "3|s|pres|ind", pres_1pl = "1|p|pres|ind", pres_2pl = "2|p|pres|ind", pres_3pl = "3|p|pres|ind", -- future tense futr_1sg = "1|s|fut|ind", futr_2sg = "2|s|fut|ind", futr_3sg = "3|s|fut|ind", futr_1pl = "1|p|fut|ind", futr_2pl = "2|p|fut|ind", futr_3pl = "3|p|fut|ind", -- imperative impr_sg = "2|s|imp", impr_pl = "2|p|imp", -- past past_m = "m|s|past|ind", past_f = "f|s|past|ind", past_n = "n|s|past|ind", past_pl = "p|past|ind", past_m_short = "short|m|s|past|ind", past_f_short = "short|f|s|past|ind", past_n_short = "short|n|s|past|ind", past_pl_short = "short|p|past|ind", -- active participles pres_actv_part = "pres|act|part", past_actv_part = "past|act|part", -- passive participles pres_pasv_part = "pres|pass|part", past_pasv_part = "past|pass|part", -- adverbial participles pres_adv_part = "pres|adv|part", past_adv_part = "past|adv|part", past_adv_part_short = "short|past|adv|part", -- infinitive infinitive = "inf", } -- Make the table make_table = function(forms, title, perf, intr, impers, notes, internal_notes, old) local infinitives = {} for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local infinitive = forms[form] if infinitive then local inf = extract_russian_tr(forms[form]) if inf ~= "-" then m_table.insertIfNot(infinitives, inf) end end end -- Group forms together for a given key and combine adjacent forms with the same -- Russian (they should always have different translits). Take care not to introduce -- manual translit unnecessarily. local grouped_forms = {} for dispform, sourceforms in pairs(disp_verb_form_map) do local entry = {} for _, form in ipairs(sourceforms) do local ru, tr = extract_russian_tr(forms[form]) -- check for empty strings, dashes and nil's if ru and ru ~= "" and ru ~= "-" and ru ~= "&mdash;" then if #entry > 0 then local lastru, lasttr = extract_russian_tr(entry[#entry]) if lastru == ru then if not lasttr and not tr or lasttr == tr then error("Russian form " .. ru .. " is duplicated, probably due to a duplicative override") end lasttr = lasttr or com.translit(lastru) tr = tr or com.translit(ru) entry[#entry] = {ru, lasttr .. " ''or'' " .. tr} else table.insert(entry, {ru, tr}) end else table.insert(entry, {ru, tr}) end end end grouped_forms[dispform] = entry end local title = (old and "Pre-reform conjugation" or "Conjugation") .. (#infinitives == 0 and "" or " of <span lang=\"ru\" class=\"Cyrl\">''" .. table.concat(infinitives, ", ") .. "''</span>") .. (title and " (" .. title .. ")" or "") local function add_links(ru, rusuf, runotes, tr, trnotes, accel) local ruspan ruspan = m_links.full_link({lang = lang, term = ru, accel = accel, tr = "-"}) if rusuf ~= "" then rusuf = "<span lang=\"ru\" class=\"Cyrl\">" .. rusuf .. "</span>" end return ruspan .. rusuf .. runotes .. "<br/>" .. require("Module:script utilities").tag_translit(tr .. trnotes, lang, "default", 'style="color:var(--wikt-palette-grey-8,#888);"') end -- NOTE: No need to check for multiple infinitives because the accel system -- doesn't support multiple lemmas. local lemma, lemmatr = extract_russian_tr(forms["infinitive"]) -- check for empty strings, dashes and nil's if lemma and lemma ~= "" and lemma ~= "-" and lemma ~= "&mdash;" then lemma = m_table_tools.separate_notes(lemma) if lemmatr then lemmatr = m_table_tools.separate_notes(lemmatr) end else -- In case the lemma is an empty string or dash, set to nil so we don't -- set a lemma in the accelerator and fall back to the page name. lemma = nil lemmatr = nil end -- Convert to displayed form local disp = {} for key, entry in pairs(grouped_forms) do for i, form in ipairs(entry) do local ru, origtr = extract_russian_tr(form) local tr = origtr or ru and com.translit(ru) local ruentry, runotes = m_table_tools.get_notes(ru) local trentry, trnotes = m_table_tools.get_notes(tr) local accel_form = accel_forms[key] if not accel_form then error("Unrecognized key " .. key .. " when looking up accelerator form") end local accel if origtr and origtr:find(" ''or'' ") then -- Multiple translits for a given Russian term. -- FIXME! Support this. accel = nil else accel = { form = accel_form, translit = origtr, lemma = lemma, lemma_translit = lemmatr} end if rfind(key, "^futr") then -- Add link to first word (form of 'to be') local tobe, inf = rmatch(ruentry, "^([^ ]*) ([^ ]*)$") if tobe then -- No accelerators for imperfective future, as it's just the future of "to be" -- plus the infinitive. entry[i] = add_links(tobe, " " .. inf, runotes, trentry, trnotes, nil) else entry[i] = add_links(ruentry, "", runotes, trentry, trnotes, accel) end else entry[i] = add_links(ruentry, "", runotes, trentry, trnotes, accel) end end disp[key] = table.concat(entry, ",<br/>") if disp[key] == "" then disp[key] = "&mdash;" end end local all_notes = {} for _, note in ipairs(internal_notes) do local symbol, entry = m_table_tools.get_initial_notes(note) table.insert(all_notes, symbol .. entry) end for _, note in ipairs(notes) do local symbol, entry = m_table_tools.get_initial_notes(note) table.insert(all_notes, symbol .. entry) end local notes_text table.insert(all_notes, 1, "Note: For declension of participles, see their entries. Adverbial participles are indeclinable.") notes_text = table.concat(all_notes, "<br />") .. "\n" return [=[<div class="NavFrame" style="max-width:49.6em;"> <div class="NavHead" style="text-align:left; background:var(--wikt-palette-lightindigo, #e9e9ff);">]=] .. title .. [=[</div> <div class="NavContent"> {| class="inflection inflection-ru inflection-verb inflection-table" |+ ]=] .. notes_text .. [=[ |- class="rowgroup" ! colspan="3" | ]=] .. (perf and [=[[[совершенный вид|perfective aspect]]]=] or [=[[[несовершенный вид|imperfective aspect]]]=]) .. [=[ |- ! [[неопределённая форма|infinitive]] | colspan="2" | ]=] .. disp.infinitive .. [=[ |- class="rowgroup" ! style="width:15em" | [[причастие|participles]] ! [[настоящее время|present tense]] ! [[прошедшее время|past tense]] |- ! [[действительный залог|active]] | ]=] .. disp.pres_actv_part .. [=[ || ]=] .. disp.past_actv_part .. [=[ |- ! [[страдательный залог|passive]] | ]=] .. disp.pres_pasv_part .. [=[ || ]=] .. disp.past_pasv_part .. [=[ |- ! [[деепричастие|adverbial]] | ]=] .. disp.pres_adv_part .. [=[ || ]=] .. disp.past_adv_part .. [=[ |- class="rowgroup" ! ! [[настоящее время|present tense]] ! [[будущее время|future tense]] |- ! [[первое лицо|1st]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">я</span>) | ]=] .. disp.pres_1sg .. [=[ || ]=] .. disp.futr_1sg .. [=[ |- ! [[второе лицо|2nd]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">ты</span>) | ]=] .. disp.pres_2sg .. [=[ || ]=] .. disp.futr_2sg .. [=[ |- ! [[третье лицо|3rd]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">он/она́/оно́</span>) | ]=] .. disp.pres_3sg .. [=[ || ]=] .. disp.futr_3sg .. [=[ |- ! [[первое лицо|1st]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">мы</span>) | ]=] .. disp.pres_1pl .. [=[ || ]=] .. disp.futr_1pl .. [=[ |- ! [[второе лицо|2nd]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">вы</span>) | ]=] .. disp.pres_2pl .. [=[ || ]=] .. disp.futr_2pl .. [=[ |- ! [[третье лицо|3rd]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">они́</span>) | ]=] .. disp.pres_3pl .. [=[ || ]=] .. disp.futr_3pl .. [=[ |- class="rowgroup" ! [[повелительное наклонение|imperative]] ! [[единственное число|singular]] ! [[множественное число|plural]] |- ! [[второе лицо|2nd]] (<span lang="ru" class="Cyrl">ты/вы</span>) | ]=] .. disp.impr_sg .. [=[ || ]=] .. disp.impr_pl .. [=[ |- class="rowgroup" ! [[прошедшее время|past tense]] ! [[единственное число|singular]] ! [[множественное число|plural]]<br/>(<span lang="ru" class="Cyrl">мы/вы/они́</span>) |- ! [[мужской род|masculine]] (<span lang="ru" class="Cyrl">я/ты/он</span>) | ]=] .. disp.past_m .. [=[ || rowspan="3" | ]=] .. disp.past_pl .. [=[ |- ! [[женский род|feminine]] (<span lang="ru" class="Cyrl">я/ты/она́</span>) | ]=] .. disp.past_f .. [=[ |- ! [[средний род|neuter]] (<span lang="ru" class="Cyrl">оно́</span>) | ]=] .. disp.past_n .. [=[ |} </div> </div>]=] end return export rno0j7hrjcr4ihczr4cfa0do83sr2b1 5672499 5672498 2026-06-29T15:08:54Z MustafaCavlak 59368 5672499 Scribunto text/plain --[=[ This module contains functions for creating inflection tables for Russian verbs. Author: Benwing, rewritten from early version by Atitarev, earliest version by CodeCat NOTE: This module is partly converted to support manual translit, in the form CYRILLIC//LATIN (i.e. with a // separating the Cyrillic and Latin parts). All the general infrastructure supports manual translit; the only thing that doesn't is some of the specific verb conjugation functions. In particular, all of the class 1, 2, 3 and 4 conjugation functions support manual translit, and the rest don't. To convert another, follow the model of one of the already-converted functions. Note that an individual form (an entry in the 'forms' table) can be either a string (no special manual translit; generally this originates from the portion of the code that doesn't support manual translit), or a one-element list {CYRILLIC} (no special manual translit), or a two-element list {CYRILLIC, LATIN} with manual translit specified. The code is careful only to generate manual translit when it's needed, to avoid penalizing the majority of cases where manual transit isn't needed. ]=] local m_str_utils = require("Modül:string araçları") local m_utilities = require("Modül:araçlar") local m_table = require("Modül:table") local m_links = require("Modül:bağlantılar") local com = require("Modül:ru-genel") local m_debug = require("Modül:debug") local m_table_tools = require("Modül:table tools") -- If enabled, compare this module with new version of module to make -- sure all conjugations are the same. local test_new_ru_verb_module = false local export = {} -- Within this module, conjugations are the functions that do the actual -- conjugating by creating the forms of a basic verb. -- They are defined further down. local conjugations = {} local lang = require("Modül:diller").getirKodaGore("ru") local u = m_str_utils.char local rfind = m_str_utils.find local rsubn = m_str_utils.gsub local rmatch = m_str_utils.match local rsplit = m_str_utils.split local usub = m_str_utils.sub local AC = u(0x0301) -- acute = ́ local DIA = u(0x0308) -- diaeresis = ̈ local PSEUDOCONS = u(0xFFF2) -- pseudoconsonant placeholder, matching ru-common local IRREG = "△" -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end -- version of rsubn() that returns a 2nd argument boolean indicating whether -- a substitution was made. local function rsubb(term, foo, bar) local retval, nsubs = rsubn(term, foo, bar) return retval, nsubs > 0 end -- Fancy version of ine() (if-not-empty). Converts empty string to nil, -- but also strips leading/trailing space and then single or double quotes, -- to allow for embedded spaces. local function ine(arg) if not arg then return nil end arg = rsub(arg, "^%s*(.-)%s*$", "%1") if arg == "" then return nil end local inside_quotes = rmatch(arg, '^"(.*)"$') if inside_quotes then return inside_quotes end inside_quotes = rmatch(arg, "^'(.*)'$") if inside_quotes then return inside_quotes end return arg end local function is_vowel_stem(stem) return rfind(stem, "[" .. com.vowel .. AC .. DIA .. "]$") end -- Return the next number to use as an internal note symbol, starting at 1. -- We look at existing internal notes to see if the symbol is already used. local function next_note_symbol(data) local nextsym = 1 while true do local sym_already_seen = false for _, note in ipairs(data.internal_notes) do if rfind(note, "^" .. nextsym .. " ") then sym_already_seen = true break end end if sym_already_seen then nextsym = nextsym + 1 else break end end return nextsym end -- FIXME: Move to utils -- Iterate over a chain of parameters, FIRST then PREF2, PREF3, ..., -- inserting into LIST (newly created if omitted). Return LIST. local function get_arg_chain(args, first, pref, list) if not list then list = {} end local val = args[first] local i = 2 while val do table.insert(list, val) val = args[pref .. i] i = i + 1 end return list end -- FIXME: Move to utils -- Set a chain of parameters, FIRST then PREF2, PREF3, ..., from LIST. local function set_arg_chain(args, first, pref, list) local param = first local i = 2 for _, val in ipairs(list) do args[param] = val param = pref .. i i = i + 1 end end local function normalize_form(form) if type(form) == "table" and m_table.length(form) == 1 then return form[1] end return form end -- For a given form in a conjugation table, we allow either strings or -- two-element lists {RUSSIAN, TRANSLIT}, where TRANSLIT can be nil -- (equivalent to a one-element list). When comparing them, we have to take -- this into account. local function forms_equal(form1, form2) return m_table.deepEquals(normalize_form(form1), normalize_form(form2)) end local function contains_form(forms, form) for _, f in ipairs(forms) do if forms_equal(f, form) then return true end end return false end -- FIXME: Move to utils -- Append to the end of a chain of parameters, FIRST then PREF2, PREF3, ..., -- if the value isn't already present. local function append_to_arg_chain(args, first, pref, newval) local nextarg = first local i = 2 if newval == "" then error("Internal error: attempt to insert blank value into arg chain") end while true do if not args[nextarg] then break end if forms_equal(args[nextarg], newval) then return nil end nextarg = pref .. i i = i + 1 end args[nextarg] = newval return nextarg end local function get_true_arg(arg, not_off_by_1) -- We normally move all params down by one because the first param is the -- verb type; so reflect this correctly if the arg is numeric and -- not_off_by_1 isn't given return (not_off_by_1 or type(arg) ~= "number") and arg or arg + 1 end local function getarg(args, arg, default, paramdesc, not_off_by_1) paramdesc = paramdesc or "Parameter " .. get_true_arg(arg, not_off_by_1) default = default or "-" --PAGENAME = mw.loadData("Modül:başlık başı/veri").pagename local NAMESPACE = mw.title.getCurrentTitle().nsText return args[arg] or (NAMESPACE == "Template" and default) or error(paramdesc .. " has not been provided") end local function check_stressed_arg(val, arg) -- don't consider suffixes if not rfind(val, "^%-") and not com.is_nonsyllabic(val) and not com.is_stressed(val) then error("Argument value " .. val .. " (parameter " .. get_true_arg(arg) .. ") must be stressed") end return val end local function get_stressed_arg(args, arg, default, paramdesc) local retval = getarg(args, arg, default, paramdesc) check_stressed_arg(retval, arg) return retval end local function get_opt_stressed_arg(args, arg) return args[arg] and get_stressed_arg(args, arg) or nil end local function check_unstressed_arg(val, arg) if com.is_stressed(val) then error("Argument value " .. val .. " (parameter " .. get_true_arg(arg) .. ") should not be stressed") end return val end local function get_unstressed_arg(args, arg, default, paramdesc) local retval = getarg(args, arg, default, paramdesc) check_unstressed_arg(retval, arg) return retval end local function get_opt_unstressed_arg(args, arg) return args[arg] and get_unstressed_arg(args, arg) or nil end local function no_stray_args(args, maxarg) for i=(maxarg + 1), 20 do if args[i] then error("Value for argument " .. get_true_arg(i) .. " not allowed (" .. args[i] .. " supplied)") end end end -- Extract a form spec (either a single string or a two-element table {RU, TR} -- into the component Russian and transliterated components. Normally, if -- an explicit manual translit wasn't given, the resulting translit will be -- nil; but if ALWAYS_TRANSLIT is given, it will be auto-transliterated from -- the Russian as needed. local function extract_russian_tr(form, always_translit) local ru, tr if type(form) == "table" then ru, tr = form[1], form[2] else ru = form end if not tr and always_translit then tr = ru and com.translit(ru) end return ru, tr end local function strip_arg_status_prefix(arg) if not arg then return arg, "" end local subbed arg, subbed = rsubb(arg, "^awkward%-", "") if subbed then return arg, "awkward-" end arg, subbed = rsubb(arg, "^none%-", "") if subbed then return arg, "none-" end return arg, "" end local function track(page) m_debug.track("ru-verb/" .. page) return true end -- Forward functions local present_e_a local present_e_b local present_e_c local present_je local present_i local make_reflexive local make_pre_reform local parse_and_stress_override local handle_forms_and_overrides local finish_generating_forms local make_table local all_verb_types = { "pf", "pf-intr", "pf-refl", "pf-impers", "pf-intr-impers", "pf-refl-impers", "impf", "impf-intr", "impf-refl", "impf-impers", "impf-intr-impers", "impf-refl-impers"} -- Examples of alternatives in use: -- past_m2: со́здал/созда́л, пе́редал/переда́л, о́тдал/отда́л, при́нялся/принялся́ -- past_m3: for verbs with three past masculine sg forms: за́нялся, заня́лся, занялс́я (заня́ться) -- past_n2: да́ло, дал́о; вз́яло, взяло́ -- past_pl2: разобрали́сь (разобрали́) -- past_m_short: short forms in 3a (исчез, сох, etc.) -- past_f_short: short forms in 3a (исчезла, сохла, etc.) -- past_n_short: short forms in 3a (исчезло, сохло, etc.) -- past_pl_short: short forms in 3a (исчезли, сохли, etc.) -- past_adv_parts: -- тереть: тере́вши, тёрши, short: тере́в -- умереть: умере́вши, у́мерши, short: умере́в -- pres_adv_part: сыпля, сыпя, лёжа (лежать) -- pres_2sg2: сыплешь, сыпешь -- pres_3sg2: сыплет, сыпет -- pres_1pl2: сыплем, сыпем -- pres_2pl2: сыплете, сыпете -- pres_3pl2: сыплют, сыпют -- futr_2sg2: насыплешь, насыпешь -- futr_3sg2: насыплет, насыпет -- futr_1pl2: насыплем, насыпем -- futr_2pl2: насыплете, насыпете -- futr_3pl2: насыплют, насыпют -- List of all main verb forms. Short forms (those ending in "_short") -- must be listed after the corresponding non-short forms. local all_main_verb_forms = { -- present tense "pres_1sg", "pres_2sg", "pres_3sg", "pres_1pl", "pres_2pl", "pres_3pl", -- future tense "futr_1sg", "futr_2sg", "futr_3sg", "futr_1pl", "futr_2pl", "futr_3pl", -- present-future tense. The conjugation functions generate the -- "present-future" tense instead of either the present or future tense, -- since the same forms are used in the present imperfect and future -- perfect. These forms are later copied into the present or future in -- finish_generating_forms(). "pres_futr_1sg", "pres_futr_2sg", "pres_futr_3sg", "pres_futr_1pl", "pres_futr_2pl", "pres_futr_3pl", -- imperative "impr_sg", "impr_pl", -- past "past_m", "past_f", "past_n", "past_pl", "past_m_short", "past_f_short", "past_n_short", "past_pl_short", -- active participles "pres_actv_part", "past_actv_part", -- passive participles "pres_pasv_part", "past_pasv_part", -- adverbial participles "pres_adv_part", "past_adv_part", "past_adv_part_short", -- infinitive "infinitive" } -- List of all verb forms. Each element is a list, where the first element -- is the "main" form and the remainder are alternatives. The following -- *MUST* hold: -- 1. Forms must be given in the order they will appear in the outputted -- table. -- 2. Short forms (those ending in "_short") must be listed after the -- corresponding non-short forms. -- 3. For each person, e.g. '2sg', there must be the same number of -- futr_PERSON, pres_PERSON and pres_futr_PERSON forms, and the alternative -- forms must be listed in the same order. -- -- FIXME!!! We should fix things so we no longer need to compute this table. local all_verb_forms = {} -- Compile all_verb_forms for _, mainform in ipairs(all_main_verb_forms) do local entry = {} table.insert(entry, mainform) for i=2,9 do table.insert(entry, mainform .. i) end table.insert(all_verb_forms, entry) end local prop_aliases = { pap="past_actv_part", paptail="past_actv_part_tail", paptailall="past_actv_part_tailall", ppp="past_pasv_part", ppptail="past_pasv_part_tail", ppptailall="past_pasv_part_tailall", prap="pres_actv_part", praptail="pres_actv_part_tail", praptailall="pres_actv_part_tailall", prpp="pres_pasv_part", prpptail="pres_pasv_part_tail", prpptailall="pres_pasv_part_tailall", padp="past_adv_part", padptail="past_adv_part_tail", padptailall="past_adv_part_tailall", padp_short="past_adv_part_short", padp_shorttail="past_adv_part_short_tail", padp_shorttailall="past_adv_part_short_tailall", pradp="pres_adv_part", pradptail="pres_adv_part_tail", pradptailall="pres_adv_part_tailall", } -- Table mapping "main" to the list of all forms in the series (e.g. -- past_m, past_m2, past_m3, etc.). If a main form (e.g. past_m) is missing, -- it needs to end up with a value of "", whereas the alternatives -- (e.g. past_m2, past_m3) need to end up with a value of nil. local main_to_all_verb_forms = {} -- List of the main verb forms for the past. local past_verb_forms = {"past_m", "past_f", "past_n", "past_pl"} -- List of the main verb forms for the present. local pres_verb_forms = {"pres_1sg", "pres_2sg", "pres_3sg", "pres_1pl", "pres_2pl", "pres_3pl"} -- List of the main verb forms for the future. local futr_verb_forms = {"futr_1sg", "futr_2sg", "futr_3sg", "futr_1pl", "futr_2pl", "futr_3pl"} -- List of the main verb forms for the imperative. local impr_verb_forms = {"impr_sg", "impr_pl"} -- List of the main verb forms for participles. local part_verb_forms = {"pres_actv_part", "past_actv_part", "pres_pasv_part", "past_pasv_part", "pres_adv_part", "past_adv_part", "past_adv_part_short"} -- List of the main verb forms for present participles. local pres_part_verb_forms = {"pres_actv_part", "pres_pasv_part", "pres_adv_part"} -- List of the main verb forms for past participles. local past_part_verb_forms = {"past_actv_part", "past_pasv_part", "past_adv_part", "past_adv_part_short"} -- Compile main_to_all_verb_forms. for _, proplist in ipairs(all_verb_forms) do main_to_all_verb_forms[proplist[1]] = proplist end -- Map listing the forms to be displayed, and the verb forms used to generate -- the displayed form, in order. For example, under past_m will be found -- {"past_m_short", "past_m", "past_m2", "past_m3"} because those forms in -- that order are displayed in the table under "masculine singular past". local disp_verb_form_map = {} for _, proplist in ipairs(all_verb_forms) do local key = proplist[1] -- if we find short forms, insert them at the beginning of the list for -- the corresponding full forms. This requires that short forms are -- listed in all_verb_forms after the corresponding full forms. if rfind(key, "_short$") then local full_key = rsub(key, "_short$", "") -- short forms should occur in list after full forms assert(#(disp_verb_form_map[full_key]) > 0) -- build entry for full form, consisting first of the short forms, -- in order, then the full forms, in order. local new_entry = {} for _, form in ipairs(proplist) do table.insert(new_entry, form) end for _, form in ipairs(disp_verb_form_map[full_key]) do table.insert(new_entry, form) end disp_verb_form_map[full_key] = new_entry elseif rfind(key, "^pres_futr") then -- skip these forms, not displayed else disp_verb_form_map[key] = mw.clone(proplist) end end local all_verb_props = mw.clone(all_verb_forms) local non_form_props = {"title", "perf", "intr", "impers", "categories", "notes", "internal_notes"} for _, prop in ipairs(non_form_props) do table.insert(all_verb_props, {prop}) end -- Clone parent's args while also assigning nil to empty strings and splitting -- arg sets (numeric args separated by "or"), assigning named args to -- all all sets. Handle aliases in the process. Extract conjugation type -- from the first arg of the arg set (for the initial arg set, this will be -- arg 2 because arg 1 is the verb type), assigning to '.conj_type' of the -- arg set. Return arg sets. local function split_args_handle_aliases(frame) local args = frame:getParent().args local arg_sets = {} local arg_set = {} -- Verb type, e.g. impf, pf, impf-intr, pf-intr, impf-refl, pf-refl, etc. -- Default to impf on the template page so that there is no script error. local verb_type = getarg(args, 1, "impf", "Verb type (first parameter)") local offset = 1 -- Find maximum-numbered arg, allowing for holes. local max_arg = 1 -- needs to be 1 not 0 so template pages display ok for pname in pairs(args) do if type(pname) == "number" and pname > max_arg then max_arg = pname end end -- Now gather the numbered arguments. for i=2,(max_arg + 1) do local end_arg_set = false if i == max_arg + 1 or args[i] == "or" then end_arg_set = true end if end_arg_set then table.insert(arg_sets, arg_set) arg_set = {} offset = i else arg_set[i - offset] = ine(args[i]) end end -- Insert named arguments into all arg sets, mapping aliases appropriately. for pname, param in pairs(args) do if type(pname) == "string" then local argval = ine(param) local mainprop, num = rmatch(pname, "^([a-z_]+)([0-9]*)$") for i=1,#arg_sets do if not mainprop then arg_sets[i][pname] = argval else mainprop = prop_aliases[mainprop] or mainprop arg_sets[i][mainprop .. num] = argval end end end end -- If we're conjugating a suffix, insert a pseudoconsonant at the beginning -- of all forms, so they get conjugated as if ending in a consonant. -- We remove the pseudoconsonant later. for i=1,#arg_sets do local asif_prefix = (arg_sets[i]["asif_prefix"] or arg_sets[i][2] and rfind(arg_sets[i][2], "^%-") and PSEUDOCONS) if asif_prefix then for k, v in pairs(arg_sets[i]) do arg_sets[i][k] = rsub(v, "^%-", "-" .. asif_prefix) end end end -- Frob conjugation type. for i=1,#arg_sets do local arg1 = arg_sets[i][1] local conj_type if arg1 then local orig_arg1 = arg1 -- This complex spec matches matches 3°a, 3oa, 4a1a, 6c1a, -- 1a6a, 6a1as13, 6a1as14, 11*b, etc. conj_type = rmatch(arg1, "^([0-9]+[*°o0-9abc]*[abc]s?1?[34]?)") arg1 = rsub(arg1, "^[0-9]+[*°o0-9abc]*[abc]s?1?[34]?", "") if not conj_type then if rfind(arg1, "^irreg") then conj_type = "irreg" arg1 = rsub(arg1, "^irreg", "") end if not conj_type then -- Check for Cyrillic, a common mistake (esp. Cyrillic а) if rfind(orig_arg1, "[абцдеѣфгчийклмнопярстувшхызёюжэщьъ]") then error("Unrecognized conjugation type (WARNING, has Cyrillic in it): " .. orig_arg1) else error("Unrecognized conjugation type: " .. orig_arg1) end end end -- The * variant is conventionally written e.g. 11*b; if found in -- the conj_type, move it to the beginning of the remainder if rfind(conj_type, "%*") then conj_type = rsub(conj_type, "%*", "") arg1 = "*" .. arg1 end arg_sets[i][1] = arg1 else local NAMESPACE = mw.title.getCurrentTitle().nsText if NAMESPACE == "Template" and i == 1 then conj_type = "1a" else error("Must specify argument 2 (conjugation type)") end end arg_sets[i]["conj_type"] = conj_type end return arg_sets, verb_type end function export.do_generate_forms(arg_sets, verb_type, old) local set1 = arg_sets[1] local notes = get_arg_chain(set1, "notes", "notes") local forms = {} local categories = {} if not m_table.contains(all_verb_types, verb_type) then error("Invalid verb type " .. verb_type) end local data = {} data.verb_type = verb_type --impersonal data.impers = rfind(verb_type, "impers") data.intr = rfind(verb_type, "intr") data.perf = rfind(verb_type, "^pf") data.iter = set1["iter"] data.nopres = set1["nopres"] data.nopast = set1["nopast"] data.nofutr = set1["nofutr"] data.noimpr = set1["noimpr"] if data.iter and data.perf then error("Iterative verbs must be imperfective") end data.old = old data.has_ppp = set1["has_ppp"] data.has_prpp = set1["has_prpp"] data.ppp_override = false data.prpp_override = false for _, form in ipairs(main_to_all_verb_forms["past_pasv_part"]) do if set1[form] then data.ppp_override = true break end end data.main_ppp_override = not not set1["past_pasv_part"] for _, form in ipairs(main_to_all_verb_forms["pres_pasv_part"]) do if set1[form] then data.prpp_override = true break end end data.internal_notes = {} local titles = {} for i=1,#arg_sets do local args = arg_sets[i] local conj_type = args.conj_type -- Support e.g. 3oa in place of 3°a conj_type = rsub(conj_type, "o", "°") track("conj-" .. conj_type) -- FIXME, convert to regular category track("conj-" .. conj_type .. "/" .. verb_type) -- FIXME, convert to regular category data.conj_type = conj_type data.cat_conj_types = {conj_type} if conj_type == "irreg" then data.title = "irregular" else data.title = conj_type end if not conjugations[conj_type] then error("Unknown conjugation type '" .. conj_type .. "'") end if args[2] then local inf, tr = com.split_russian_tr(args[2]) if rfind(inf, "[тч]ься$") then inf = rsub(inf, "ся$", "") tr = com.strip_tr_ending(tr, "ся") data.refl = true elseif rfind(inf, "ти́?сь$") then -- 7a (вы́вестись), 7b (вести́сь) or derivative of -йти́ (разойти́сь) inf = rsub(inf, "сь$", "") tr = com.strip_tr_ending(tr, "сь") data.refl = true elseif rfind(inf, "[тч]ь$") then -- Allow monosyllabic infinitives to be specified without stress if com.is_monosyllabic(inf) and not rfind(inf, "^%-") then inf, tr = com.make_ending_stressed(inf, tr) end end if tr then args[2] = inf .. "//" .. tr else args[2] = inf end end if data.refl and data.intr then error("Can't specify -intr with reflexive verbs") end if data.has_ppp or data.has_prpp then if data.refl then error("Can't specify has_ppp=y or has_prpp=y with reflexive verbs") end if not data.intr then error("Can only specify has_ppp=y or has_prpp=y with intransitive verbs") end end data.shouldnt_have_ppp = data.refl or not data.has_ppp and data.intr data.shouldnt_have_prpp = data.refl or not data.has_prpp and data.intr if data.ppp_override and data.shouldnt_have_ppp then error("Shouldn't specify past passive participle with reflexive or intransitive verbs, if it's needed use has_ppp=y") elseif data.perf and not data.shouldnt_have_ppp and not data.ppp_override then -- possible omissions track("perfective-no-ppp") end if data.prpp_override and data.shouldnt_have_prpp then error("Shouldn't specify present passive participle with reflexive or intransitive verbs, if it's needed use has_prpp=y") end -- Call conjugation function. It will return a table of forms -- as if it's the first arg set. If it is in fact the first -- arg set, we just use the table directly (we may destructively -- modify it if there are later arg sets, but this is OK because -- no one else but us uses the table). Otherwise we need to -- append the values from the table to those of the previous -- arg sets. local arg_set_forms = conjugations[conj_type](args, data) if i == 1 then forms = arg_set_forms else for _, all_forms in pairs(main_to_all_verb_forms) do for _, form in ipairs(all_forms) do if arg_set_forms[form] then append_to_arg_chain(forms, all_forms[1], all_forms[1], arg_set_forms[form]) end end end end m_table.insertIfNot(titles, data.title) if conj_type == "irreg" then table.insert(categories, "Russian irregular verbs") end -- For irregular verbs, if the verb didn't set a specific cat_conj_type, -- it will be the same as the conj_type and be "irreg". In that case, -- replace it with the title, which might be a proper conjugation type -- like 4a or 8c/b (and remove anything starting with a slash, to -- account for cases like 8c/b). After doing this, the cat_conj_type -- might still begin with "irreg" (for sufficiently irregular verbs that -- they can't be assigned to any of the normal classes), in which case -- we don't create a class for the verb beyond "Russian irregular verbs" -- (set above). if data.cat_conj_types[1] == "irreg" then data.cat_conj_types = {rsub(rsub(data.title, "/.*", ""), "[*⑨]", "")} end for _, cat_conj_type in ipairs(data.cat_conj_types) do if not rmatch(cat_conj_type, "^irreg") then local class_num = rmatch(cat_conj_type, "^([0-9]+)") assert(class_num and class_num ~= "") table.insert(categories, "Russian class " .. class_num .. " verbs") table.insert(categories, "Russian class " .. cat_conj_type .. " verbs") end end end data.title = "class " .. table.concat(titles, " // ") .. (data.perf and " perfective" or " imperfective") .. (data.refl and " reflexive" or data.intr and " intransitive" or " transitive") .. (data.impers and " impersonal" or "") .. (data.iter and " iterative" or "") -- Perfective/imperfective if data.perf then table.insert(categories, "Russian perfective verbs") else table.insert(categories, "Russian imperfective verbs") end handle_forms_and_overrides(set1, forms, data) local function remove_pseudo(str) local toremove = set1["asif_prefix"] or PSEUDOCONS if str == nil then return str end str = rsub(str, "^%-" .. toremove, "-") -- also handle prefix after space, e.g. in futures str = rsub(str, " %-" .. toremove, " -") return str end -- Remove pseudoconsonant we may have inserted; if no ending, insert -- "(no suffix)". for k in pairs(forms) do if forms[k] == "-" .. PSEUDOCONS or type(forms[k] == "table") and forms[k][1] == "-" .. PSEUDOCONS then -- Make the translit empty. forms[k] = {"(no suffix)", ""} else if type(forms[k]) == "table" then forms[k][1] = remove_pseudo(forms[k][1]) forms[k][2] = remove_pseudo(forms[k][2]) else forms[k] = remove_pseudo(forms[k]) end end end -- Catch errors in verb arguments that lead to the infinitive not matching -- page title, but only in the main namespace. local NAMESPACE = mw.title.getCurrentTitle().nsText if NAMESPACE == "" then local PAGENAME = mw.loadData("Modül:başlık başı/veri").pagename for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local inf = extract_russian_tr(forms[form]) if inf then inf, _ = m_table_tools.separate_notes(inf) -- remove any footnote symbols (e.g. грясти́) local inf_noaccent = com.remove_accents(inf) if inf ~= "-" then if data.refl then if rfind(inf_noaccent, "и$") then inf_noaccent = inf_noaccent .. "сь" inf = inf .. "сь" else inf_noaccent = inf_noaccent .. "ся" inf = inf .. "ся" end end if inf_noaccent ~= PAGENAME then error("Infinitive " .. inf .. " doesn't match pagename " .. PAGENAME) end end end end end -- Reflexive/intransitive/transitive if set1["reflex_stress"] then track("reflex-stress") end if data.refl then local reflex_stress = set1["reflex_stress"] or data.default_reflex_stress -- "ся́" make_reflexive(forms, reflex_stress and reflex_stress ~= "n" and reflex_stress ~= "no") table.insert(categories, "Russian reflexive verbs") elseif data.intr then table.insert(categories, "Russian intransitive verbs") else table.insert(categories, "Russian transitive verbs") end -- Impersonal if data.impers then table.insert(categories, "Russian impersonal verbs") end -- Iterative if data.iter then table.insert(categories, "Russian iterative verbs") end if data.old then make_pre_reform(forms) end finish_generating_forms(forms, data) return forms, data.title, data.perf, data.intr or data.refl, data.impers, categories, notes, data.internal_notes end local function fetch_forms(forms) local function fetch_one_form(form) local val = forms[form] local ru, tr if type(val) == "table" then ru, tr = val[1], val[2] elseif type(val) == "string" and val ~= "" and val ~= "-" then ru = val end if not ru then return nil end local ruentry = m_table_tools.get_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.get_notes(tr) end -- There shouldn't be any links. -- ruentry = m_links.remove_links(ruentry) -- There shouldn't be any vertical bars. -- ruentry = rsub(ruentry, "|", "<!>") -- if trentry then -- trentry = rsub(trentry, "|", "<!>") -- end return trentry and ruentry .. "//" .. trentry or ruentry end local vals = {} for _, proplist in ipairs(all_verb_forms) do local vallist = {} local propname = proplist[1] if not rfind(propname, "^pres_futr") then for _, prop in ipairs(proplist) do local val = fetch_one_form(prop) if val then table.insert(vallist, val) end end if #vallist > 0 then table.insert(vals, propname .. "=" .. table.concat(vallist, ",")) end end end return table.concat(vals, "|") end function export.generate_forms(frame) local arg_sets, verb_type = split_args_handle_aliases(frame) local old = frame.args["old"] or arg_sets[1]["old"] local forms = export.do_generate_forms(arg_sets, verb_type, old) return fetch_forms(forms) end -- The main entry point. -- This is the only function that can be invoked from a template. function export.show(frame) local arg_sets, verb_type = split_args_handle_aliases(frame) local old = frame.args["old"] or arg_sets[1]["old"] local arg_sets_clone if test_new_ru_verb_module then -- arg_sets may be modified by do_generate_forms() arg_sets_clone = mw.clone(arg_sets) end local forms, title, perf, intr, impers, categories, notes, internal_notes = export.do_generate_forms(arg_sets, verb_type, old) -- Test code to compare existing module to new one. if test_new_ru_verb_module then local m_new_ru_verb = require("Modül:User:Benwing2/ru-verb") local newforms, newtitle, newperf, newintr, newimpers, newcategories, newnotes, newinternal_notes = m_new_ru_verb.do_generate_forms(arg_sets_clone, verb_type, old) local vals = mw.clone(forms) vals.title = title vals.perf = perf vals.intr = intr vals.impers = impers vals.categories = categories vals.notes = notes vals.internal_notes = internal_notes local newvals = mw.clone(newforms) newvals.title = newtitle newvals.perf = newperf newvals.intr = newintr newvals.impers = newimpers newvals.categories = newcategories newvals.notes = newnotes newvals.internal_notes = newinternal_notes local difconj = false for _, proplist in ipairs(all_verb_props) do for _, prop in ipairs(proplist) do local val = vals[prop] local newval = newvals[prop] -- deal with impedance mismatch between old style (plain string) -- and new style (Russian/translit array), and empty string vs. nil if not m_table.contains(non_form_props, prop) then if type(val) == "string" then val = {val} end if val and val[1] == "" then val = nil end if type(newval) == "string" then newval = {newval} end if newval and newval[1] == "" then newval = nil end end -- Ignore changes in pres_futr_*, which aren't displayed if not forms_equal(val, newval) and not rfind(prop, "^pres_futr") then -- Uncomment this to display the particular case and -- differing forms. --error(prop .. " " .. (val and concat_vals(val) or "nil") .. " || " .. (newval and concat_vals(newval) or "nil")) difconj = true break end end end track(difconj and "different-conj" or "same-conj") end return make_table(forms, title, perf, intr, impers, notes, internal_notes, old) .. m_utilities.format_categories(categories, lang) end --[=[ Functions for working with stems, paradigms, Russian/translit ]=] -- Combine a stem with optional translit with an ending and possibly a foonote -- symbol (which may be a tuple {RUNOTES, TRNOTES}), returning a tuple -- {RUSSIAN, TR}. local function combine(stem, tr, ending, note) if not ending or ending == "-" then return nil end local arg_status ending, arg_status = strip_arg_status_prefix(ending) if stem ~= "" and com.is_stressed(ending) then stem, tr = com.make_unstressed_once(stem, tr) end stem = arg_status .. stem if not note then return com.concat_russian_tr(stem, tr, ending, nil, "dopair") else local runotes, trnotes = extract_russian_tr(note) local ruending, trending = com.concat_russian_tr(ending, nil, runotes, trnotes) return com.concat_russian_tr(stem, tr, ruending, trending, "dopair") end end -- Set an individual form PARAM in FORMS with value based on stem STEM (with -- optional translit TR), ENDINGS (either a single string or a list of strings) -- and NOTE (nil, a string, or a tuple {RUSSIAN, TR}). If there are multiple -- endings listed, they will go successively into PARAM, PARAM2, etc. -- (e.g. past_m, past_m2, etc.). local function set_form(forms, param, stem, tr, endings, note) if type(endings) ~= "table" then endings = {endings} end local entries = {} for _, val in ipairs(endings) do m_table.insertIfNot(entries, combine(stem, tr, val, note)) end set_arg_chain(forms, param, param, entries) end -- Append to an individual form PARAM in FORMS with value based on stem STEM -- (with optional translit TR), ENDINGS (either a single string or a list of -- strings) and NOTE (nil, a string, or a tuple {RUSSIAN, TR}). If there are -- multiple endings listed, they will go successively into PARAM, PARAM2, etc. -- (e.g. past_m, past_m2, etc.), provided there are no existing forms already -- present. Duplicate forms aren't inserted. local function append_form(forms, param, stem, tr, endings, note) if type(endings) ~= "table" then endings = {endings} end for _, val in ipairs(endings) do append_to_arg_chain(forms, param, param, combine(stem, tr, val, note)) end end local function append_pres_futr(forms, stem, tr, sg1, sg2, sg3, pl1, pl2, pl3, note) append_form(forms, "pres_futr_1sg", stem, tr, sg1, note) append_form(forms, "pres_futr_2sg", stem, tr, sg2, note) append_form(forms, "pres_futr_3sg", stem, tr, sg3, note) append_form(forms, "pres_futr_1pl", stem, tr, pl1, note) append_form(forms, "pres_futr_2pl", stem, tr, pl2, note) append_form(forms, "pres_futr_3pl", stem, tr, pl3, note) end local function append_participles_2stem(forms, pres_stem, pres_tr, past_stem, past_tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, pres_note, past_note) append_form(forms, "pres_actv_part", pres_stem, pres_tr, pres_actv, pres_note) append_form(forms, "pres_pasv_part", pres_stem, pres_tr, pres_pasv, pres_note) append_form(forms, "pres_adv_part", pres_stem, pres_tr, pres_adv, pres_note) append_form(forms, "past_actv_part", past_stem, past_tr, past_actv, past_note) append_form(forms, "past_adv_part", past_stem, past_tr, past_adv, past_note) append_form(forms, "past_adv_part_short", past_stem, past_tr, past_adv_short, past_note) end local function append_participles(forms, stem, tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, note) append_participles_2stem(forms, stem, tr, stem, tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, note, note) end local function set_ppp(forms, stem, tr, ending, note) set_form(forms, "past_pasv_part", stem, tr, ending, note) end local function append_ppp(forms, stem, tr, ending, note) append_form(forms, "past_pasv_part", stem, tr, ending, note) end local function append_imper(forms, stem, tr, sg, pl, note) append_form(forms, "impr_sg", stem, tr, sg, note) append_form(forms, "impr_pl", stem, tr, pl, note) end local function set_past(forms, stem, tr, m, f, n, pl, note) set_form(forms, "past_m", stem, tr, m, note) set_form(forms, "past_f", stem, tr, f, note) set_form(forms, "past_n", stem, tr, n, note) set_form(forms, "past_pl", stem, tr, pl, note) end local function append_past(forms, stem, tr, m, f, n, pl, note) append_form(forms, "past_m", stem, tr, m, note) append_form(forms, "past_f", stem, tr, f, note) append_form(forms, "past_n", stem, tr, n, note) append_form(forms, "past_pl", stem, tr, pl, note) end -- Prepend a possibly-stressed prefix to all forms; if prefix is stressed, -- destress the forms before prepending. FIXME: Should support explicit -- manual translit. local function prepend_prefix(forms, prefix, pre_two_cons_prefix) pre_two_cons_prefix = pre_two_cons_prefix or prefix local stressed_prefix = com.is_stressed(prefix) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) if tr then error("Explicit manual translit not yet supported") end -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then if stressed_prefix then ru = com.make_unstressed(ru) end if rfind(ru, "^[" .. com.cons .. "][" .. com.cons .. "]") then forms[key] = pre_two_cons_prefix .. ru else forms[key] = prefix .. ru end end end end -- Apply regex substitution FROM -> TO to all forms. FIXME: Should support -- explicit manual translit. local function rsub_forms(forms, from, to) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) if tr then error("Explicit manual translit not yet supported") end -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then forms[key] = rsub(ru, from, to) end end end local variant_to_title = { ["[(2)]"] = "[②]", ["(2)"] = "②", ["[(3)]"] = "[③]", ["(3)"] = "③", ["[(4)]"] = "[④]", ["(4)"] = "④", ["[(5)]"] = "[⑤]", ["(5)"] = "⑤", ["[(6)]"] = "[⑥]", ["(6)"] = "⑥", ["[(7)]"] = "[⑦]", ["(7)"] = "⑦", ["[(8)]"] = "[⑧]", ["(8)"] = "⑧", ["(9)"] = "⑨", ["щ"] = "(-щ-)", ["ё"] = "(-ё-)", ["о"] = "(-о-)", ["жд"] = "(-жд-)", } local function prepare_past_stress_indicator(past_stress) if not past_stress or past_stress == "a" then return "" end past_stress = rsub(past_stress, "%(1%)", "①") past_stress = rsub(past_stress, "(.),%1①", "%1[①]") past_stress = rsub(past_stress, "(.)①,%1", "%1[①]") past_stress = rsub(past_stress, "''", "&#39;&#39;") past_stress = rsub(past_stress, "-nd", "") past_stress = rsub(past_stress, "-bd", "") return "/" .. past_stress end local function parse_variants(data, variants, allowed) -- Need to set these to nil in case of multiple arg sets data.imper_variant = nil data.var4 = nil data.var5 = nil data.var6 = nil data.ppp = nil data.var9 = nil data.shch = nil data.yo = nil data.o = nil data.zhd = nil data.star = nil variants = variants or "" local variant_title = "" if variants ~= "" then -- short-circuit the most common case -- Only recognize * variant for long-variant prefix at the beginning -- of the variant code block (where it gets moved if it's in the -- middle of the conjugation type, as it normally is) because a * -- also occurs in b*, a past stress variant code. if rfind(variants, "^%*") then -- Specify that the present/future tense has extra -о in the prefix: -- types 9*b (e.g. растере́ть, futr_1sg разотру́) and 11*b (e.g. изли́ть, -- futr_1sg изолью́). It can also occur with type 7*b (in -че́сть, -- e.g. счесть, сочту́; расче́сть, разочту́) and type 8*b (in -же́чь, e.g. -- сжечь, сожгу́) but these are always irregular and require the -- present tense to be specified explicitly. It can also occur -- with type 14*b (e.g. размя́ть, разомну́; сжать, сожну́; подожа́ть, подожму́), -- but for these verbs the present tense is unpredictable and -- must be specified explicitly. -- -- This can also occur where the extra -о occurs in the infinitive -- and past, but not the present tense: type 5*c (in -гна́ть, e.g. -- согна́ть, сгоню́; разогна́ться, разгоню́сь), type 6*c (in -стла́ть, e.g. -- подостла́ть, подстелю́; разостла́ть, расстелю́), type 6°*c -- (in -зва́ть, -бра́ть, -дра́ть, e.g. подозва́ть, подзову́; разобра́ться, разберу́сь); -- but these are always irregular and require the present tense -- to be specified explicitly. if not m_table.contains(allowed, "*") then error("Variant " .. var .. " not allowed for this verb class") end data.star = true variants = rsub(variants, "^*", "") end -- Allow brackets around both 5 and 6, e.g. [(5)(6)] variants = rsub(variants, "%[(%([56]%))(%([56]%))%]", "[%1][%2]") -- Handle all remaining variants. We do this using an rsub() function, -- where we pull out, parse and remove each variant in turn. variants = rsub(variants, "(%[?%(?[23456789ёощийьж+][дp]?%)?%]?)", function(var) if m_table.contains({"(2)", "[(2)]", "(3)", "[(3)]", "и", "й", "ь"}, var) then if data.imper_variant then error("Saw two imperative variants " .. data.imper_variant .. " and " .. var) end local is_23 = m_table.contains({"(2)", "[(2)]", "(3)", "[(3)]"}, var) if is_23 and not m_table.contains(allowed, "23") or not is_23 and not m_table.contains(allowed, "и") then error("Variant " .. var .. " not allowed for this verb class") end data.imper_variant = var elseif m_table.contains({"(4)", "[(4)]"}, var) then if data.var4 then error("Saw two variant-4 specs " .. data.var4 .. " and " .. var) end if not m_table.contains(allowed, "4") then error("Variant " .. var .. " not allowed for this verb class") end data.var4 = var == "(4)" and "req" or "opt" elseif m_table.contains({"(5)", "[(5)]"}, var) then if data.var5 then error("Saw two variant-5 specs " .. data.var5 .. " and " .. var) end if not m_table.contains(allowed, "5") then error("Variant " .. var .. " not allowed for this verb class") end data.var5 = var == "(5)" and "req" or "opt" elseif m_table.contains({"(6)", "[(6)]"}, var) then if data.var6 then error("Saw two variant-6 specs " .. data.var6 .. " and " .. var) end if not m_table.contains(allowed, "6") then error("Variant " .. var .. " not allowed for this verb class") end data.var6 = var == "(6)" and "req" or "opt" elseif m_table.contains({"(7)", "[(7)]", "(8)", "[(8)]", "+p"}, var) then if data.shouldnt_have_ppp then error("Shouldn't specify past passive participle with reflexive or intransitive verbs, if it's needed use has_ppp=y") end if data.ppp then error("Saw two past passive participle specs " .. data.ppp .. " and " .. var) end if m_table.contains({"(7)", "[(7)]"}, var) and not m_table.contains(allowed, "7") or m_table.contains({"(8)", "[(8)]"}, var) and not m_table.contains(allowed, "8") or var == "+p" and not m_table.contains(allowed, "+p") then error("Variant " .. var .. " not allowed for this verb class") end data.ppp = var elseif var == "(9)" then if data.var9 then error("Saw (9) twice") end if not m_table.contains(allowed, "9") then error("Variant " .. var .. " not allowed for this verb class") end data.var9 = true elseif var == "щ" then -- specify that the 1sg pres/futr and past passive participle -- of class 4/5/6 verbs iotate -т to -щ instead of -ч; cf. -- похи́тить (похи́щу) (4a), защити́ть (защищу́) (4b), -- поглоти́ть (поглощу́) (4c), клевета́ть (клевещу́) (6c) if data.shch then error("Saw щ twice") end if not m_table.contains(allowed, "щ") then error("Variant " .. var .. " not allowed for this verb class") end data.shch = "щ" elseif var == "ё" then -- specify that the past passive participle has ё instead of е if data.yo then error("Saw ё twice") end if not m_table.contains(allowed, "ё") then error("Variant " .. var .. " not allowed for this verb class") end data.yo = true elseif var == "о" then -- specify that the past passive participle has о instead of е -- NOTE: Not currently allowed as a user-specifiable variant if data.o then error("Saw о twice") end if not m_table.contains(allowed, "о") then error("Variant " .. var .. " not allowed for this verb class") end data.o = true elseif var == "жд" then -- specify that the past passive participle of class 4/5/6 verbs -- iotates -д to -жд instead of -ж if data.zhd then error("Saw жд twice") end if not m_table.contains(allowed, "жд") then error("Variant " .. var .. " not allowed for this verb class") end data.zhd = true else error("Unrecognized variant spec: " .. var) end variant_title = variant_title .. (variant_to_title[var] or "") return "" end) variant_title = rsub(variant_title, "%[⑤%]%[⑥%]", "[⑤⑥]") end if variants ~= "" and not m_table.contains(allowed, "past") then error("Past stress " .. variants .. " not allowed for this verb class") end if data.yo and not data.ppp then error("Variant ё specified without calling for past passive participle") end if data.o and not data.ppp then error("Variant о specified without calling for past passive participle") end if data.zhd and not data.ppp then error("Variant жд specified without calling for past passive participle") end if data.perf and not data.ppp and not data.ppp_override and not data.shouldnt_have_ppp and not data.impers then error("For perfective transitive verbs, need to specify past passive participle by variant or override; use |ppp=- if no such participle") end data.past_stress = variants == "" and "a" or rsub(variants, "/", "") data.title = data.title .. prepare_past_stress_indicator(data.past_stress) .. variant_title if data.star then data.title = rsub(data.title, "^([0-9]+°?)", "%1*") end -- If there's an override of past_pasv_part, generate the normal participle -- so we can determine whether the override is irregular. But set a flag -- so we erase any automatically generated past passive participles that -- aren't overridden. This happens for example in обнять, where there are -- two automatically generated past passive participles but a single -- ppp=о́внятый override. if not data.ppp and data.main_ppp_override then data.ppp = "+p" data.ppp_auto_generated = true end end local function set_past_by_stress(forms, past_stresses, prefix, prefixtr, base, basetr, args, data, no_pastml, note) -- If there isn't manual translit for the prefix, we need to supply it -- if there's manual translit for the base, because we often concatenate -- prefix to the base. local prefixtr = prefixtr or basetr and com.translit(prefix) for _, past_stress in ipairs(rsplit(past_stresses, ",")) do local pastml = no_pastml and "" or "л" local stressed_prefix, stressed_prefixtr if prefix == "пере" then stressed_prefix = "пе́ре" stressed_prefixtr = "pe" .. AC .. "re" elseif prefix == "раз" then stressed_prefix = "ро́з" stressed_prefixtr = "ro" .. AC .. "z" elseif prefix == "рас" then -- Does this ever occur? stressed_prefix = "ро́с" stressed_prefixtr = "ro" .. AC .. "s" elseif prefix == "ра" and rfind(base, "^[сз]") then -- Type 9/11/14/16 with automatically split prefix; may never happen. stressed_prefix = "ро́" stressed_prefixtr = "ro" .. AC else stressed_prefix, stressed_prefixtr = com.make_ending_stressed(prefix, prefixtr) end -- Normally the base is stressed and the prefix isn't, but it could -- be the other way around, e.g. in запереть and запереться, where -- the stress on the prefix is used to get prefix-stressed participles. -- To deal with this, we usually combine base and prefix unchanged, -- but in combination with stressed_prefix we always want an unstressed -- base, and when a stressed -ся́ is called for, we want both of them -- unstressed. local ubase, ubasetr = com.make_unstressed(base, basetr) local uprefix, uprefixtr = com.make_unstressed(prefix, prefixtr) -- If the prefix is stressed (вы́-), we need to use the unstressed base to avoid getting double stress. local prefixbase = com.is_stressed(prefix) and prefix .. ubase or prefix .. base local prefixbasetr = basetr and (com.is_stressed(prefix) and prefixtr .. ubasetr or prefixtr .. basetr) local stressed_prefix_ubase = stressed_prefix .. ubase local stressed_prefix_ubasetr = ubasetr and stressed_prefixtr .. ubasetr local uprefixubase = uprefix .. ubase local uprefixubasetr = ubasetr and uprefixtr .. ubasetr if past_stress == "a" then -- (/под/пере/при/по)забы́ть, раздобы́ть, (/пере/по)забы́ться append_past(forms, prefixbase, prefixbasetr, pastml, "ла", "ло", "ли", note) elseif past_stress == "a(1)" then -- вы́дать, вы́быть, etc.; also проби́ть with the meaning -- "to strike (of a clock)" (which is a(1),a or similar) append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) -- Retraction to prefix doesn't happen in feminine singular, see the -- bottom of page 81 of Zaliznyak's 1980 grammar. append_past(forms, prefixbase, prefixbasetr, {}, "ла", {}, {}, note) elseif past_stress == "b" then append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", "ло́", "ли́", note) elseif past_stress == "b*" then if not data.refl then error("Only reflexive verbs can take past stress variant " .. past_stress) end -- See comment in type c''. We want to see whether we actually -- added an argument, and if so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. (note or ""))) if argset and not args[argset] and not data.impers then data.default_reflex_stress = "ся́" end append_past(forms, prefixbase, prefixbasetr, {}, "ла́", "ло́", "ли́", note) elseif past_stress == "c" then -- изда́ть, возда́ть, сдать, пересозда́ть, воссозда́ть, надда́ть, наподда́ть, etc. -- быть, избы́ть, сбыть -- клясть, закля́сть append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", "ло", "ли", note) elseif past_stress == "c(1)" then -- прибы́ть, убы́ть -- прокля́сть -- also, c(1),c: -- зада́ть, обда́ть, отда́ть, подда́ть, переда́ть (пе́редал), преда́ть, прода́ть, разда́ть (ро́здал), созда́ть, etc. -- отбы́ть, побы́ть, пробы́ть -- also, c,c(1): -- добы́ть -- Because the prefix may vary depending on stress (esp. for -- раздать [ро́здал/раздала́]), we need to separate the endings that -- take the stressed prefix and those that take the unstressed -- prefix with stressed ending. append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) append_past(forms, prefixbase, prefixbasetr, {}, "ла́", {}, {}, note) elseif past_stress == "c'" then -- дать --same with "взять" append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", {"ло", "ло́"}, "ли", note) elseif past_stress == "c''" or past_stress == "c''-nd" or past_stress == "c''-bd" then if not data.refl then error("Only reflexive verbs can take past stress variant " .. past_stress) end -- c'' (-ся́ dated): all verbs in -да́ться; избы́ться, сбы́ться; all verbs in -кля́сться -- c''-nd (-ся́ not dated): various verbs in -ня́ться per Zaliznyak -- c''-bd (-ся́ becoming dated): various verbs in -ня́ться per ruwikt local note_symbol = past_stress == "c''-nd" and "" or next_note_symbol(data) append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", {"ло́", "ло"}, {"ли́", "ли"}) -- We want to see whether we actually added an argument, and if -- so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. note_symbol .. (note or ""))) -- Only display the internal note and set the default reflex -- stress if the form with the note will be displayed (i.e. not -- impersonal, and no override of this form). FIXME: We should -- have a more general mechanism to check for this. if not args[argset] and not data.impers then local note = past_stress == "c''" and note_symbol .. " Dated." or past_stress == "c''-bd" and note_symbol .. " Becoming dated." or nil if note then m_table.insertIfNot(data.internal_notes, note) end data.default_reflex_stress = "ся́" end elseif past_stress == "c''(1)" then -- запере́ться -- See comment in type c''. We want to see whether we actually -- added an argument, and if so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. (note or ""))) if argset and not args[argset] and not data.impers then data.default_reflex_stress = "ся́" end append_past(forms, prefixbase, prefixbasetr, {}, "ла́", "ло́", "ли́", note) append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) else error("Unrecognized past-stress value " .. past_stress .. ", should be a, a(1), b, b*, c, c(1), c', c'', c''-nd, c''-bd, c''(1) or comma-separated list") end end end -- Split a verb stem into a possibly multisyllabic prefix (пере-, переиз-, -- воссоз-, повы́-, etc.) and a single-syllable main verb (-тер-, -ли́-, -гре́-, -- etc.). Normally the splitting is done simply by looking for alternating -- vowel/consonant sequences, meaning that e.g. разгре́ will be split as -- ра + згре́ and растер will be split as ра + стер. For most purposes, this -- doesn't matter, but for the * variant it does; in that case, if it is -- known that the main verb base always begins with a single consonant, -- specify SINGLE_CONS_BASE and then e.g. растер will be split as рас + тер. local function split_monosyllabic_main_verb(ru, tr, single_cons_base) local rusyl, trsyl = com.split_syllables(ru, tr) local last_ru = rusyl[#rusyl] local last_tr = trsyl and trsyl[#trsyl] table.remove(rusyl, #rusyl) local prefix_ru = table.concat(rusyl, "") local prefix_tr if trsyl then table.remove(trsyl, #trsyl) prefix_tr = table.concat(trsyl, "") end if single_cons_base then local cons_to_move, rest = rmatch(last_ru, "^([" .. com.cons .. "]+)([" .. com.cons .. "].*)$") if cons_to_move then prefix_ru = prefix_ru .. cons_to_move last_ru = rest end if last_tr then cons_to_move, rest = rmatch(last_tr, "^([" .. com.tr_cons .. "]+)([" .. com.tr_cons .. "].*)$") if cons_to_move then prefix_tr = prefix_tr .. cons_to_move last_tr = rest end end end return prefix_ru, prefix_tr, last_ru, last_tr end local function split_known_main_verb(arg, mains) -- Given an argument (which may be RUSSIAN//TR), split the prefix from -- the main verb, which should be one of the verbs in MAINS (which can be -- a -- single verb or a list of verbs, but in either case all verbs -- need to be stressed). This correctly handles stressed and unstressed -- prefixes. local stem, tr = com.split_russian_tr(arg) if type(mains) ~= "table" then mains = {mains} end for _, main in ipairs(mains) do assert(com.is_stressed(main)) if rfind(stem, main .. "$") then stem, tr = com.strip_ending(stem, tr, main) if com.is_stressed(stem) then error("Two stresses in " .. arg) end return stem, tr, main, nil end main = com.make_unstressed_once(main) if rfind(stem, main .. "$") then stem, tr = com.strip_ending(stem, tr, main) if com.is_unstressed(stem) then error("No stresses in " .. arg) end return stem, tr, main, nil end end if #mains == 1 then error("Argument " .. arg .. " doesn't end in " .. mains[1]) else error("Argument " .. arg .. " doesn't end in any of " .. table.concat(mains, ",")) end end local function construct_long_prefix_variant(prefix) if rfind(prefix, "рас$") then return rsub(prefix, "рас$", "разо") end if rfind(prefix, "ис$") then return rsub(prefix, "ис$", "изо") end if rfind(prefix, "вс$") then return rsub(prefix, "вс$", "взо") end return prefix .. "о" end local function append_imper_by_variant(forms, stem, tr, variant, verbclass, note) local vowel_stem = is_vowel_stem(stem) local stress = rmatch(verbclass, "([abc])$") if not stress then error("Unrecognized verb class '" .. verbclass .. "', should end with a, b or c") end local longend = stress == "a" and "и" or "и́" local shortend = vowel_stem and (com.is_unstressed(stem) and "́й" -- accent on previous vowel or "й") or "ь" local function append_short_imper() append_imper(forms, stem, tr, shortend, shortend .. "те", note) end local function append_long_imper() append_imper(forms, stem, tr, longend, longend .. "те", note) end if variant and variant ~= "" then track("explicit-imper") track("explicit-imper/" .. verbclass) end if variant == "(2)" then -- use short variants with вы́- (for these verbs, long is expected) if not rfind(stem, "^вы́-") then error("Should only specify imperative variant (2) with verbs in вы́-, not " .. stem) end append_short_imper() elseif variant == "[(2)]" then -- use both long and short variants append_long_imper() append_short_imper() elseif variant == "(3)" then -- long in singular, short in plural append_imper(forms, stem, tr, longend, shortend .. "те", note) elseif variant == "[(3)]" then -- long and short in singular, short in plural append_imper(forms, stem, tr, {longend, shortend}, shortend .. "те", note) elseif variant == "ь" or variant == "й" then -- short variants wanted append_short_imper() elseif variant == "и" then -- long variants wanted append_long_imper() else assert(not variant or variant == "") if vowel_stem then if verbclass == "4b" or verbclass == "4c" or ( verbclass == "4a" and rfind(stem, "^вы́-")) then append_long_imper() else append_short_imper() end else -- consonant stem if stress == "b" or stress == "c" then append_long_imper() else assert(stress == "a") -- "и" after вы́-, e.g. вы́садить -- "и" after final щ, e.g. тара́щиться (although this particular -- verb has a [(3)] spec attached to it) if rfind(stem, "^вы́-") or rfind(stem, "щ$") or -- "и" after two consonants in a row (мо́рщить, зафре́ндить) rfind(stem, "[бвгджзклмнпрстфхцчшщь][бвгджзклмнпрстфхцчшщ]$") then append_long_imper() else -- "ь" after a single consonant (бре́дить) append_short_imper() end end end end end -- Compute the past passive participle stem for verbs that require it to be -- iotated (class 4, and class 5 in -еть). local function iotated_ppp(data, stem, tr) local iotated_stem, iotated_tr if data.zhd then local subbed iotated_stem, subbed = rsubb(stem, "з?д$", "жд") if not subbed then error("Variant -жд- specified but stem " .. stem .. " doesn't end in -д") end if tr then iotated_tr, subbed = rsubb(tr, "z?d$", "žd") if not subbed then error("Variant -жд- specified but translit " .. tr .. " doesn't end in -d") end end else iotated_stem, iotated_tr = com.iotation(stem, tr, data.shch) end return iotated_stem, iotated_tr end -- Set the past passive participle of verbs where the stress is moved left -- from the ending by one syllable (if possible) if the ending is stressed, -- otherwise left as-is (except class 1a in -е́ть, which has ending-stressed -- -ённый). This applies to classes 1, 2, 3, 5, 6, 10 and 13. The stem comes -- from the infinitive, iotated in class 5 -еть/-ѣть verbs. The participle -- ending is -анный/-янный for verbs in -ать/-ять, -енный/-ённый for verbs in -еть, -- -ѣнный/-ѣ̈нный for verbs in -ѣть, otherwise -тый. local function set_moving_ppp(forms, data) if not data.ppp then return end -- NOTE: No need to check for multiple infinitives because no verbs have -- them normally, and we probably don't want to check for overrides here -- (e.g. it would break достичь and related verbs, which have participles -- based on the infinitive достигнуть). local infinitive, infinitivetr = extract_russian_tr(forms["infinitive"]) local stem, ending = rmatch(infinitive, "^(.*)([аеѣоуя]́?ть)$") if not stem then error("Strange infinitive " .. infinitive .. " when trying to create participle") end local tr, endingtr if infinitivetr then if ending == "ять" or ending == "я́ть" then tr, endingtr = rmatch(infinitivetr, "^(.*)(ja" .. AC .. "?tʹ)$") else tr, endingtr = rmatch(infinitivetr, "^(.*)([aeěou]" .. AC .. "?tʹ)$") end if not tr then error("Translit " .. infinitivetr .. " doesn't match Cyrillic " .. infinitive) end end local ending_vowel = usub(ending, 1, 1) local ppptype = data.ppp if com.is_nonsyllabic(stem) then -- e.g. 3b гну́ть (гну́тый); but not -нуть (type 3a, as a suffix) ppptype = "(7)" end if m_table.contains({"5a", "5b", "5c"}, data.conj_type) and (ending_vowel == "е" or ending_vowel == "ѣ") then stem, tr = iotated_ppp(data, stem, tr) end if not com.is_stressed(stem) then stem, tr = com.make_ending_stressed(stem, tr) end if data.o then -- цев -> цо́в, e.g. (об)лицева́ть -> (об)лицо́ванный stem = rsub(stem, "е́", "о́") -- Cyrillic if tr then tr = rsub(tr, "e" .. AC, "o" .. AC) -- Latin end elseif data.yo then -- ё occurs with e.g. 1a наверста́ть (навёрстанный) -- ё occurs with e.g. 3b поверну́ть (повёрнутый) -- ё occurs with e.g. 5b лежа́ть (лёжанный) but not with 5c держа́ть -- (де́ржанный) -- ё occurs always with class 2 in -ева́ть, e.g. -- (за)тушева́ть ((за)тушёванный) and (за)клева́ть ((за)клёванный) local subbed stem, subbed = rsubb(stem, "е́", "ё") -- Cyrillic if not subbed and data.old then stem, subbed = rsub(stem, "ѣ́", "ѣ̈") end if not subbed then error("No stressed е" .. (data.old and " or ѣ" or "") .. " in stem " .. stem .. " to replace with ё" .. (data.old and " or ѣ̈" or "") .. " when trying to create participle") end if tr then tr, subbed = rsub(tr, "j[eě]" .. AC, "jo" .. AC) -- Latin if not subbed then tr, subbed = rsub(tr, "[eě]" .. AC, "jo" .. AC) -- Latin end if not subbed then error("No stressed е in translit " .. tr .. " to replace with jo when trying to create participle") end end end if data.conj_type == "1a" and ending_vowel == "е" then -- 1a, only одоле́ть, преодоле́ть, verbs in -печатле́ть set_ppp(forms, stem, tr, "ённый") elseif data.conj_type == "1a" and ending_vowel == "ѣ" then set_ppp(forms, stem, tr, "ѣ̈нный") else local stressed_ending, unstressed_ending if ending_vowel == "е" then stressed_ending = "ённый" unstressed_ending = "енный" elseif ending_vowel == "ѣ" then stressed_ending = "ѣ̈нный" unstressed_ending = "ѣнный" else local ppp_ending = (ending_vowel == "а" or ending_vowel == "я") and "нный" or "тый" stressed_ending = ending_vowel .. AC .. ppp_ending unstressed_ending = ending_vowel .. ppp_ending end set_ppp(forms, stem, tr, -- (7) occurs with 1a обуя́ть (обуя́нный) ppptype == "(7)" and stressed_ending or -- [(7)] -- when does it occur? may only occur in class 4 ppptype == "[(7)]" and {unstressed_ending, stressed_ending} or unstressed_ending) end end -- Iterate over the values of a property (e.g. past_m, past_f), handling -- overrides properly. Call FN on each one, passing in RU, TR, NOTE. local function iterate_over_prop(forms, args, prop, fn) for _, form in ipairs(main_to_all_verb_forms[prop]) do local ru, tr if args[form] then local orig_forms = {} for _, form2 in ipairs(main_to_all_verb_forms[prop]) do if forms[form2] then table.insert(orig_forms, forms[form2]) end end local override = parse_and_stress_override(form, args[form], forms[form], orig_forms) ru, tr = extract_russian_tr(override) end if (not ru or ru == "" or ru == "-") and forms[form] then ru, tr = extract_russian_tr(forms[form]) end -- skip unstressed forms (may occur in the past_m when a stressed -- reflexive -ся́ should occur; these occur only in запереться and -- опереться, where they're used to generate the past active part -- and past adverbial part, and end-stressed forms shouldn't be -- generated) if ru and ru ~= "" and ru ~= "-" and not com.is_unstressed(ru) then local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) end fn(ruentry, trentry, {runotes, trnotes}) end end end -- Set the past passive participle for those classes where it is derived -- from the past tense masculine singular (9, 11, 12, 14, 15, 16). We need -- to apply any relevant overrides. local function set_ppp_from_past_m(forms, args, data) if not data.ppp then return end iterate_over_prop(forms, args, "past_m", function(ru, tr, note) if rfind(ru, "л$") then ru = rsub(ru, "л$", "") if tr then tr = rsub(tr, "l$", "") end end append_ppp(forms, ru, tr, "тый", note) end) end -- Set the past passive participle for class-4 verbs. local function set_class_4_ppp(forms, data, stem, tr, vclass) if not data.ppp then return end local iotated_stem, iotated_tr = iotated_ppp(data, stem, tr) vclass = vclass or data.conj_type if vclass == "4b" then local stressed_iotated_stem, stressed_iotated_tr = com.make_ending_stressed(iotated_stem, iotated_tr) set_ppp(forms, stressed_iotated_stem, stressed_iotated_tr, -- (8) occurs with 4b скрои́ть (скро́енный) data.ppp == "(8)" and "енный" or -- [(8)] occurs with 4b разгроми́ть (разгромлённый, разгро́мленный) data.ppp == "[(8)]" and {"ённый", "енный"} or "ённый") else set_ppp(forms, iotated_stem, iotated_tr, -- (7) occurs with 4c раздели́ть (разделённый) data.ppp == "(7)" and "ённый" or -- [(7)] occurs with 4a осве́домить (осве́домленный, осведомлённый) -- [(7)] occurs with 4c иссуши́ть (иссу́шенный, иссушённый) data.ppp == "[(7)]" and {"енный", "ённый"} or "енный") end end -- Set the past passive participle for class-7 and class-8 verbs. These -- form the PPP by adding to the base of the 3sg pres/futr (i.e. minus -- -ет/-ёт). The stress follows the stress of the past singular feminine. -- Only types a, a(1) and b exist, meaning that if the past singular feminine -- is ending-stressed then the PPP ending is -ённый, otherwise it is -енный -- with the stress of the 3sg pres/futr base preserved (and added to the -- last syllable if the base has no stress, as in 7b укра́сть, 3sg украдёт, -- fem sg past укра́ла, PPP укра́денный). local function set_class_7_8_ppp(forms, args, data) if not data.ppp then return end local sg3_bases = {} -- Extract 3sg bases. There may be more than one possible form, e.g. in -- обокра́сть, so support this. -- FIXME: We don't support checking for overrides here; doing so isn't -- overly hard but is a bit tricky because the overrides will be either -- pres_3sg or futr_3sg, depending on the aspect of the verb. -- FIXME: We don't support manual translit here, because neither 7 nor 8 -- support it elsewhere. for _, form in ipairs(main_to_all_verb_forms["pres_futr_3sg"]) do local ru, tr if forms[form] then ru, tr = extract_russian_tr(forms[form]) end if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) ruentry = rsub(ruentry, "[её]т$", "") if com.is_unstressed(ruentry) then ruentry = com.make_ending_stressed(ruentry) end m_table.insertIfNot(sg3_bases, {ruentry, runotes}) end end -- Here we do the same rigmarole as in set_ppp_from_past_m(), to respect -- any past_f overrides that might have been set. It's unlikely that -- there is more than one possible form but we support it. iterate_over_prop(forms, args, "past_f", function(ru, tr, note) for _, base_and_notes in ipairs(sg3_bases) do local base, notes = base_and_notes[1], base_and_notes[2] append_ppp(forms, base, nil, -- check if past_f is ending-stressed rfind(ru, AC .. "$") and "ённый" or "енный", notes) end end) end --[=[ Conjugation functions ]=] conjugations["1a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7", "ё"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) if stem == "-" and not tr then -- Template space; leave it else stem, tr = com.strip_ending(stem, tr, "ть") end no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "ть") append_participles(forms, stem, tr, "ющий", "емый", "я", "вший", "вши", "в") set_moving_ppp(forms, data) present_je(forms, stem, tr, "a") append_imper(forms, stem, tr, "й", "йте") set_past(forms, stem, tr, "л", "ла", "ло", "ли") return forms end local function guts_of_2(args, data) local forms = {} local inf_stem, inf_tr = com.split_russian_tr(get_stressed_arg(args, 2)) inf_stem, inf_tr = com.strip_ending(inf_stem, inf_tr, "ть") no_stray_args(args, 2) local pres_stem, pres_tr = inf_stem, inf_tr local variants = args[1] or "" parse_variants(data, variants, {"+p", "7"}) -- If stem ends in -ева́ть and a past passive participle is called for -- with stress on the -е-, automatically set -о- or -ё- as required. if data.ppp and data.ppp ~= "(7)" then if rfind(inf_stem, "цева́") then if data.ppp == "[(7)]" then -- FIXME. Theoretically we should support this but there -- aren't any verbs requiring it. It won't work properly -- currently because we need the о to appear only when -- stressed. error("Variant [(7)] not supported for class 2") end -- цев -> цо́в, e.g. (об)лицева́ть -> (об)лицо́ванный data.o = true data.title = data.title .. "(-о-)" elseif rfind(inf_stem, "ева́") then data.yo = true data.title = data.title .. "(-ё-)" end end -- all -ова- change to -у- pres_stem = rsub(pres_stem, "о(́?)ва(́?)$", "у%1%2") pres_tr = pres_tr and rsub(pres_tr, "o(́?)va(́?)$", "u%1%2") -- -ева- change to -ю- after most consonants and vowels, to -у- after hissing sounds and ц if rfind(pres_stem, "[бвгдзклмнпрстфхь" .. com.vowel .. AC .. "]е(́?)ва(́?)$") then pres_stem = rsub(pres_stem, "е(́?)ва(́?)$", "ю%1%2") pres_tr = pres_tr and rsub(pres_tr, "e(́?)va(́?)$", "ju%1%2") elseif rfind(pres_stem, "[жцчшщ]е(́?)ва(́?)$") then pres_stem = rsub(pres_stem, "е(́?)ва(́?)$", "у%1%2") pres_tr = pres_tr and rsub(pres_tr, "e(́?)va(́?)$", "u%1%2") end forms["infinitive"] = combine(inf_stem, inf_tr, "ть") if data.conj_type == "2a" then append_participles_2stem(forms, pres_stem, pres_tr, inf_stem, inf_tr, "ющий", "емый", "я", "вший", "вши", "в") present_je(forms, pres_stem, pres_tr, "a") else append_participles_2stem(forms, pres_stem, pres_tr, inf_stem, inf_tr, "ю́щий", "-", "я́", "вший", "вши", "в") present_je(forms, pres_stem, pres_tr, "b") end set_moving_ppp(forms, data) append_imper(forms, pres_stem, pres_tr, "й", "йте") set_past(forms, inf_stem, inf_tr, "л", "ла", "ло", "ли") return forms end conjugations["2a"] = function(args, data) return guts_of_2(args, data) end conjugations["2b"] = function(args, data) return guts_of_2(args, data) end conjugations["3°a"] = function(args, data) local forms = {} -- (5), [(6)] or similar; imperative indicators parse_variants(data, args[1], {"5", "6", "23", "и", "+p", "7", "ё"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = com.strip_ending(stem, tr, "нуть") local vowel_stem = is_vowel_stem(stem) no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "нуть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "нущий", "-", "-", data.var6 == "req" and "нувший" or data.var6 == "opt" and (vowel_stem and {"вший", "нувший"} or {"ший", "нувший"}) or vowel_stem and "вший" or "ший", data.var6 == "req" and "нувши" or data.var6 == "opt" and (vowel_stem and {"вши", "нувши"} or {"ши", "нувши"}) or vowel_stem and "вши" or "ши", data.var6 == "req" and "нув" or data.var6 == "opt" and (vowel_stem and {"в", "нув"} or "нув") or vowel_stem and "в" or "-") set_moving_ppp(forms, data) present_e_a(forms, stem .. "н", tr and tr .. "n") append_imper_by_variant(forms, stem .. "н", tr and tr .. "n", data.imper_variant, "3°a") forms["past_m"] = data.var5 and combine(stem, tr, "нул") or "-" forms["past_m_short"] = data.var5 ~= "req" and combine(stem, tr, (vowel_stem and "л" or "")) or nil forms["past_f_short"] = combine(stem, tr, "ла") forms["past_n_short"] = combine(stem, tr, "ло") forms["past_pl_short"] = combine(stem, tr, "ли") return forms end conjugations["3a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"23", "и", "+p", "7", "ё"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) -- make sure we can strip нуть from the stem and any translit; com.strip_ending(stem, tr, "нуть") -- but then just strip the -уть and leave the н stem, tr = com.strip_ending(stem, tr, "уть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "уть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "ущий", "-", "-", "увший", "увши", "ув") set_moving_ppp(forms, data) present_e_a(forms, stem, tr) append_imper_by_variant(forms, stem, tr, data.imper_variant, "3a") set_past(forms, stem .. "ул", tr and tr .. "ul", "", "а", "о", "и") return forms end local function guts_of_3b_3c(args, data, vclass) local forms = {} parse_variants(data, args[1], {"+p", "7", "ё"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) -- make sure we can strip нуть from the stem and any translit; com.strip_ending(stem, tr, "ну́ть") -- but then just strip the -у́ть and leave the н stem, tr = com.strip_ending(stem, tr, "у́ть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "у́ть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "у́щий", "-", "-", "у́вший", "у́вши", "у́в") set_moving_ppp(forms, data) append_imper(forms, stem, tr, "и́", "и́те") set_past(forms, stem, tr, "у́л", "у́ла", "у́ло", "у́ли") if data.conj_type == "3b" then present_e_b(forms, stem, tr) else stem, tr = com.make_ending_stressed(stem, tr) present_e_c(forms, stem, tr) end return forms end conjugations["3b"] = function(args, data) return guts_of_3b_3c(args, data) end conjugations["3c"] = function(args, data) return guts_of_3b_3c(args, data) end conjugations["4a"] = function(args, data) local forms = {} -- imperative variants, also щ, used for verbs like похитить (похи́щу) (4a), -- защитить (защищу́) (4b), поглотить (поглощу́) (4c) with a different -- iotation (т -> щ, not ч) parse_variants(data, args[1], {"23", "и", "щ", "past", "+p", "7", "жд"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = com.strip_ending(stem, tr, "ить") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "ить") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") append_participles(forms, stem, tr, hushing and "ащий" or "ящий", "awkward-имый", hushing and "а" or "я", "ивший", "ивши", "ив") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "a", data.shch) append_imper_by_variant(forms, stem, tr, data.imper_variant, "4a") -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem .. "и", tr and tr .. "i", args, data) return forms end conjugations["4a1a"] = function(args, data) local forms = {} data.title = "4a // 1a" data.cat_conj_types = {"1a", "4a"} -- imperative variants, also щ, used for verbs like похитить (похи́щу) (4a), -- защитить (защищу́) (4b), поглотить (поглощу́) (4c) with a different -- iotation (т -> щ, not ч) parse_variants(data, args[1], {"23", "и", "щ", "past", "+p", "7", "жд"}) local stem4, tr4 = com.split_russian_tr(get_stressed_arg(args, 2)) stem4, tr4 = com.strip_ending(stem4, tr4, "ить") local hushing = rfind(stem4, "[шщжч]$") local stem1, tr1 if hushing then stem1 = stem4 .. "а" tr1 = tr4 and tr4 .. "a" else stem1 = stem4 .. "я" tr1 = tr4 and tr4 .. "ja" end no_stray_args(args, 2) forms["infinitive"] = combine(stem4, tr4, "ить") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. append_participles(forms, stem4, tr4, hushing and "ащий" or "ящий", "awkward-имый", hushing and "а" or "я", "ивший", "ивши", "ив") append_participles(forms, stem1, tr1, "ющий", "емый", "я", {}, {}, {}) set_class_4_ppp(forms, data, stem4, tr4) present_i(forms, stem4, tr4, "a", data.shch) present_je(forms, stem1, tr1, "a", data.shch) append_imper_by_variant(forms, stem4, tr4, data.imper_variant, "4a") append_imper(forms, stem1, tr1, "й", "йте") -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem4 .. "и", tr4 and tr4 .. "i", args, data) return forms end conjugations["4b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"щ", "past", "+p", "8", "жд"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = com.strip_ending(stem, tr, "и́ть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "и́ть") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") append_participles(forms, stem, tr, hushing and "а́щий" or "я́щий", "awkward-и́мый", hushing and "а́" or "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "b", data.shch) append_imper(forms, stem, tr, "и́", "и́те") -- set prefix to "" as past stem may vary in length and no (1) variants local stem_noa, tr_noa = com.make_unstressed_once(stem, tr) set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "и́", tr_noa and tr_noa .. "i" .. AC, args, data) return forms end conjugations["4c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"щ", "4", "past", "+p", "7", "жд"}) local stem, tr = com.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = com.strip_ending(stem, tr, "и́ть") stem, tr = com.make_ending_stressed(stem, tr) no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "и́ть") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") local prap_end_stressed = hushing and "а́щий" or "я́щий" local prap_stem_stressed = hushing and "ащий" or "ящий" append_participles(forms, stem, tr, data.var4 == "req" and prap_stem_stressed or data.var4 == "opt" and {prap_end_stressed, prap_stem_stressed} or prap_end_stressed, "awkward-и́мый", hushing and "а́" or "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "c", data.shch) append_imper(forms, stem, tr, "и́", "и́те") local stem_noa, tr_noa = com.make_unstressed_once(stem, tr) set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "и́", tr_noa and tr_noa .. "i" .. AC, args, data) return forms end -- Combined class 5. But there's enough conditional code that it might make -- more sense to separate them again. local function guts_of_5(args, data) local forms = {} local is5a = data.conj_type == "5a" local is5b = data.conj_type == "5b" -- imperative ending (выгнать - выгони) and past stress; imperative is -- "й" after any vowel (e.g. выстоять), with or without an acute accent, -- otherwise ь or и if is5a or is5b then parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё"}) else parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё", "4"}) end local inf = get_stressed_arg(args, 2) local past_stem = com.strip_ending(inf, nil, "ть") local stem = is5b and get_opt_unstressed_arg(args, 3) or get_opt_stressed_arg(args, 3) local default_stem = rmatch(past_stem, "^(.*)[еѣая]́?$") if not default_stem then error("Argument " .. inf .. " doesn't end in еть, ѣть, ать or ять") end if not is5a and not is5b then default_stem = com.make_ending_stressed(default_stem) end stem = stem or default_stem local pres_note = stem ~= default_stem and IRREG no_stray_args(args, 3) forms["infinitive"] = past_stem .. "ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") if is5a then append_participles_2stem(forms, stem, nil, past_stem, nil, hushing and "ащий" or "ящий", "имый", hushing and "а" or "я", "вший", "вши", "в", pres_note) elseif is5b then append_participles_2stem(forms, stem, nil, past_stem, nil, hushing and "а́щий" or "я́щий", "и́мый", hushing and "а́" or "я́", "вший", "вши", "в", pres_note) else -- var4 occurs with at least терпре́ть and дыша́ть local prap_end_stressed = hushing and "а́щий" or "я́щий" local prap_stem_stressed = hushing and "ащий" or "ящий" append_participles_2stem(forms, stem, nil, past_stem, nil, data.var4 == "req" and prap_stem_stressed or data.var4 == "opt" and {prap_end_stressed, prap_stem_stressed} or prap_end_stressed, "и́мый", hushing and "а́" or "я́", "вший", "вши", "в", pres_note) end set_moving_ppp(forms, data) present_i(forms, stem, nil, is5a and "a" or is5b and "b" or "c", nil, pres_note) append_imper_by_variant(forms, stem, nil, data.imper_variant, data.conj_type, pres_note) -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, past_stem, nil, args, data) return forms end conjugations["5a"] = function(args, data) return guts_of_5(args, data) end conjugations["5b"] = function(args, data) return guts_of_5(args, data) end conjugations["5c"] = function(args, data) return guts_of_5(args, data) end -- Implement 6a, 6°a, 6a1as13, 6a1as14, and 1a6a. local function guts_of_6a(args, data, vclass) local forms = {} -- Type 6a1a, section 13: -- Forms of both 6a and 1a can occur. They are the same in the infinitive -- and past. In the present active participle and the present/future, the -- type 6 forms are preferred and the type 1a forms are colloquial. In the -- remaining present forms and the imperative, both are equally preferred -- (we put the type-6 forms first because Zaliznyak lists them first). -- Type 6a1a section 14, type 1a6a: -- Forms of both 6a and 1a can occur. They are the same in the infinitive -- and past. In the present adverbial participle and the imperative, the -- type 1a forms are preferred and the type 6a forms are dated. In the -- remaining present forms, one or the other is slightly preferred (type -- 6a for 6a1a, type 1a for 1a6a). if vclass == "6a1as13" or vclass == "6a1as14" then data.title = "6a // 1a" data.cat_conj_types = {"1a", "6a"} elseif vclass == "1a6a" then data.title = "1a // 6a" data.cat_conj_types = {"1a", "6a"} end parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё"}) local inf = get_stressed_arg(args, 2) local inf_past_stem = com.strip_ending(inf, nil, "ть") local stem = rmatch(inf_past_stem, "^(.*)[ая]́?$") if not stem then error("Argument " .. inf .. " doesn't end in ать or ять") end if com.is_unstressed(stem) then -- колыха́ть, колеба́ть, etc. stem = com.make_ending_stressed(stem) end -- вызвать - вы́зову (в́ызов) local pres_stem = get_opt_stressed_arg(args, 3) or stem no_stray_args(args, 3) local pres_note = pres_stem ~= stem and IRREG -- no iotation, e.g. вырвать - вы́рву local no_iotation = vclass == "6°a" -- replace consonants for 1st person singular present/future local iotated_stem = no_iotation and pres_stem or com.iotation(pres_stem) forms["infinitive"] = inf_past_stem .. "ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") or no_iotation -- Participles -- pres_pasv_part is normal if infinitive ends in -ять, nonexistent except -- with certain lexical exceptions (колеба́ть, колыха́ть, глаго́лать, -- дви́гать with exceptional form дви́жимый) if infinitive ends in -ать local prpp_status = rfind(inf_past_stem, "я́?$") and "" or "none-" if vclass == "6a" or vclass == "6°a" or vclass == "6a1as13" then append_participles_2stem(forms, iotated_stem, nil, inf_past_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", hushing and "а" or "я", "вший", "вши", "в", pres_note) if vclass == "6a1as13" then -- then all the type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий*", prpp_status .. "емый", "я") end elseif vclass == "6a1as14" then -- first the preferred type 6a present active/passive participles append_participles(forms, iotated_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", {}, {}, {}, {}, pres_note) -- then all the type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий", "емый", "я", "вший", "вши", "в") -- then the dated type 6a present adverbial participle append_participles(forms, iotated_stem, nil, {}, {}, hushing and "а*" or "я*", {}, {}, {}, pres_note) else -- type 1a6a -- first the preferred type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий", "емый", "я", "вший", "вши", "в") -- then the type 6a forms (dated in present adverbial participle) append_participles(forms, iotated_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", hushing and "а*" or "я*", {}, {}, {}, pres_note) end set_moving_ppp(forms, data) -- Present/future tense local function class_6_present() if no_iotation then present_e_a(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "a", nil, pres_note) end end if vclass == "6a" or vclass == "6°a" then class_6_present() elseif vclass == "1a6a" then -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a") class_6_present() elseif vclass == "6a1as14" then class_6_present() -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a") else -- 6a1as13 class_6_present() -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a", nil, "*") end -- Imperative forms; if 1a6a or 6a1as14, type 6a forms are dated; -- if 6a1as13, type 6a forms go first. local function class_1_impr() append_imper(forms, inf_past_stem, nil, "й", "йте") end local function class_6_impr() local dated_note = ((vclass == "6a1as14" or vclass == "1a6a") and "*" or "") .. (pres_note or "") append_imper_by_variant(forms, iotated_stem, nil, data.imper_variant, "6a", dated_note) end if vclass == "6a1as14" or vclass == "1a6a" then class_1_impr() class_6_impr() elseif vclass == "6a1as13" then class_6_impr() class_1_impr() else class_6_impr() end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, inf_past_stem, nil, args, data) if vclass == "6a1as14" or vclass == "1a6a" then m_table.insertIfNot(data.internal_notes, "* Dated.") elseif vclass == "6a1as13" then m_table.insertIfNot(data.internal_notes, "* Colloquial; type-6 forms preferred.") end return forms end conjugations["6a"] = function(args, data) return guts_of_6a(args, data, "6a") end conjugations["6°a"] = function(args, data) return guts_of_6a(args, data, "6°a") end conjugations["6a1as13"] = function(args, data) return guts_of_6a(args, data, "6a1as13") end conjugations["6a1as14"] = function(args, data) return guts_of_6a(args, data, "6a1as14") end conjugations["1a6a"] = function(args, data) return guts_of_6a(args, data, "1a6a") end -- implement 6b, 6°b local function guts_of_6b(args, data, vclass) local forms = {} parse_variants(data, args[1], {"past", "+p", "7", "ё"}) local inf = get_stressed_arg(args, 2) local stem = rmatch(inf, "^(.*)[ая]́ть$") if not stem then error("Argument " .. inf .. " doesn't end in ать or ять") end -- звать - зов, драть - дер local pres_stem = get_opt_unstressed_arg(args, 3) or stem no_stray_args(args, 3) -- no iotation, e.g. рвать - рву local no_iotation = vclass == "6°b" local vowel_end_stem = is_vowel_stem(stem) local pres_note = pres_stem ~= stem and IRREG if no_iotation then present_e_b(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "b", nil, pres_note) end local impr_end = vowel_end_stem and "́й" -- accent on the preceding vowel or "и́" append_imper(forms, pres_stem, nil, impr_end, impr_end .. "те", pres_note) -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(pres_stem, "[шщжч]$") -- no pres_pasv_part local past_stem_with_vowel = stem .. (vowel_end_stem and "я́" or "а́") append_participles_2stem( forms, pres_stem, nil, past_stem_with_vowel, nil, ((hushing or no_iotation) and "у́щий" or "ю́щий"), {}, (hushing and "а́" or "я́"), "вший", "вши", "в", pres_note) forms["infinitive"] = combine(past_stem_with_vowel, nil, "ть") set_moving_ppp(forms, data) -- past_f for ждала́, подождала́ now handled through general mechanism --for разобрало́сь, past_n2 разобрало́ now handled through general mechanism --for разобрали́сь, past_pl2 разобрали́ now handled through general mechanism -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem .. (vowel_end_stem and "я́" or "а́"), nil, args, data) return forms end conjugations["6b"] = function(args, data) return guts_of_6b(args, data, "6b") end conjugations["6°b"] = function(args, data) return guts_of_6b(args, data, "6°b") end -- Implement 6c, 6°c and 6c1a. local function guts_of_6c(args, data, vclass) local forms = {} -- In type 6c1a, forms of both 6c and 1a can occur. They are -- the same in the infinitive and past. In the present active participle -- and the present/future, the type 6c forms are preferred and the type 1a -- forms are colloquial. In the remaining present forms and the imperative, -- both are equally preferred (we put the 6c forms first because Zaliznyak -- lists 6c first). if vclass == "6c1a" then data.title = "6c // 1a" data.cat_conj_types = {"1a", "6c"} end -- optional щ parameter for verbs like клеветать (клевещу́), past stress parse_variants(data, args[1], {"щ", "past", "+p", "7", "ё"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "а́ть") stem = com.make_ending_stressed(stem) -- разостла́ть - расстелю́, рассте́лешь local pres_stem = get_opt_stressed_arg(args, 3) or stem no_stray_args(args, 3) local pres_note = pres_stem ~= stem and IRREG -- remove accent for some forms local stem_noa = com.make_unstressed(stem) -- applies only to стона́ть, застона́ть, простона́ть local no_iotation = vclass == "6°c" -- iotate the stem local iotated_stem = no_iotation and pres_stem or com.iotation(pres_stem, nil, data.shch) local stem1a = stem_noa .. "а́" forms["infinitive"] = stem_noa .. "а́ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") -- Participles append_participles_2stem(forms, iotated_stem, nil, stem_noa, nil, (hushing or no_iotation) and "ущий" or "ющий", {}, hushing and "а́" or "я́", "а́вший", "а́вши", "а́в", pres_note) if vclass == "6c1a" then -- then all the type 1a forms (both are the same in the past) append_participles(forms, stem1a, nil, "ющий*", "емый", "я") end set_moving_ppp(forms, data) if no_iotation then present_e_c(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "c", data.shch, pres_note) end append_imper(forms, iotated_stem, nil, "и́", "и́те", pres_note) if vclass == "6c1a" then present_je(forms, stem1a, nil, "a", nil, "*") append_imper(forms, stem1a, nil, "й", "йте") end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "а́", nil, args, data) if vclass == "6c1a" then m_table.insertIfNot(data.internal_notes, "* Colloquial; type-6 forms preferred.") end return forms end conjugations["6c"] = function(args, data) return guts_of_6c(args, data, "6c") end conjugations["6°c"] = function(args, data) return guts_of_6c(args, data, "6°c") end conjugations["6c1a"] = function(args, data) return guts_of_6c(args, data, "6c1a") end local function convert_last_e_to_yo(form) return rsub(form, "([еѣ])[́̀̈]*([^" .. com.vowel .. "]*)$", function(e, nonvowels) return (e == "е" and "ё" or "ѣ̈") .. nonvowels end) end local function guts_of_7(args, data, forms) local is7b = data.conj_type == "7b" local full_inf = get_stressed_arg(args, 2) local pres_stems = is7b and get_unstressed_arg(args, 3) or get_stressed_arg(args, 3) pres_stems = rsplit(pres_stems, ",") local past_stem if past_stem ~= "ёе" then past_stem = get_opt_stressed_arg(args, 4) end local past_stem_vowel_alt = past_stem == "ёе" if past_stem_vowel_alt then past_stem = nil end no_stray_args(args, 4) forms["infinitive"] = full_inf -- Construct the default past and present stem by a combination of -- infinitive and present final consonant. -- (1) Deduce the final consonant. local final_cons for _, pres_stem in ipairs(pres_stems) do -- Final cons is -ст if pres stem ends in vowel + ст, else -- single final cons [дтсзбп] (no actual examples of final п). -- Note that final -з can occur after a consonant (e.g. ползти́). local this_final_cons = rmatch(pres_stem, "[" .. com.vowel .. "]" .. AC .. "?(ст)$") if not this_final_cons then this_final_cons = rmatch(pres_stem, "([дтсзбп])$") end if not this_final_cons then error("Unable to determine final consonant from present stem " .. pres_stem) end if final_cons and this_final_cons ~= final_cons then error("Present stems with conflicting final consonants specified: " .. table.concat(pres_stems, ",")) end final_cons = this_final_cons end -- (2) Find the infinitive minus the termination. local prefix = rmatch(full_inf, "^(.*)[сз]т[иь]" .. AC .."?$") if not prefix then error("Strange infinitive " .. full_inf .. "in class 7") end -- (3) Combine infinitive with final consonant. local default_pres_stem = prefix .. final_cons if is7b then default_pres_stem = com.make_unstressed(default_pres_stem) end local default_past_stem = default_pres_stem if com.is_unstressed(default_past_stem) then default_past_stem = com.make_ending_stressed(default_past_stem) end -- (4) Past stems ending in -д and -т when the infinitive ends in -сть (but not -сти or -сти́) -- lose this consonant (page 85 of Zaliznyak, see also footnote 2 on that page). if rfind(full_inf, "сть$") then default_past_stem = rsub(default_past_stem, "[дт]$", "") end -- (5) If 7b and the past stem wasn't originally specified as ёе, the past stem gets -- ё in place of е. if is7b and not past_stem_vowel_alt then default_past_stem = convert_last_e_to_yo(default_past_stem) end for _, pres_stem in ipairs(pres_stems) do local pres_note = pres_stem ~= default_pres_stem and IRREG if is7b then present_e_b(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и́", "и́те", pres_note) else present_e_a(forms, pres_stem, nil, pres_note) append_imper_by_variant(forms, pres_stem, nil, data.imper_variant, "7a", pres_note) end end -- Construct the past stem if not specified. Note that we then derive a separate -- past-tense stem from this stem, and this stem as such ends up applying only -- to the past active and adverbial participles. if not past_stem then past_stem = default_past_stem end local past_note = past_stem ~= default_past_stem and IRREG -- Derive the past tense stem from the past stem derived above. This has ё instead of е -- in 7b verbs; it also loses д and т in all cases, when the past stem derived above only loses -- these consonants in some cases. local past_tense_stem = past_stem if is7b then past_tense_stem = convert_last_e_to_yo(past_tense_stem) end past_tense_stem = rsub(past_tense_stem, "[дт]$", "") local vowel_pp = is_vowel_stem(past_stem) local pap = vowel_pp and "вши" or "ши" local var9_note_symbol = next_note_symbol(data) for _, pres_stem in ipairs(pres_stems) do local pres_note = pres_stem ~= default_pres_stem and IRREG append_participles_2stem(forms, pres_stem, nil, past_stem, nil, is7b and "у́щий" or "ущий", "-", is7b and "я́" or "я", vowel_pp and "вший" or "ший", data.var9 and {is7b and "я́" or "я", pap .. var9_note_symbol} or pap, vowel_pp and not data.var9 and "в" or "-", pres_note, past_note) end if data.var9 then m_table.insertIfNot(data.internal_notes, var9_note_symbol .. " Dated.") end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, past_tense_stem, nil, args, data, -- 0 ending if the past stem ends in a consonant not is_vowel_stem(past_tense_stem) and "no-pastml", past_note) -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) end conjugations["7a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"23", "и", "9","past", "+p"}) -- лезть - ле́зши - non-existent past_actv_part handled through general mechanism guts_of_7(args, data, forms) return forms end conjugations["7b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"9", "past", "+p"}) guts_of_7(args, data, forms) return forms end local function class_8a_stem_to_infinitive(stem) -- map e.g. вы́сек back to высе́чь return rsub(stem, "[гк]$", "чь") end local function class_8b_stem_to_infinitive(stem) -- map e.g. отвлёк back to отвле́чь -- map e.g. зажёг back to заже́чь return com.make_ending_stressed(rsub(rsub(rsub(stem, "ё", "е"), "ѣ̈", "ѣ"), "[гк]$", "чь")) end conjugations["8a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local full_inf = get_stressed_arg(args, 2) local stem = get_stressed_arg(args, 3) local stressed_past_stem = get_opt_stressed_arg(args, 4) or stem no_stray_args(args, 4) forms["infinitive"] = full_inf local pres_note = class_8a_stem_to_infinitive(stem) ~= full_inf and IRREG local stressed_past_note = class_8a_stem_to_infinitive(stressed_past_stem) ~= full_inf and IRREG -- default for pres_pasv_part is blank append_participles_2stem(forms, stem, nil, stressed_past_stem, nil, "ущий", "-", "-", "ший", "ши", "-", pres_note, stressed_past_note) local iotated_stem = com.iotation(stem) append_pres_futr(forms, iotated_stem, nil, {}, "ешь", "ет", "ем", "ете", {}, pres_note) append_pres_futr(forms, stem, nil, "у", {}, {}, {}, {}, "ут", pres_note) append_imper(forms, stem, nil, "и", "ите", pres_note) -- set prefix to "" as stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem, nil, args, data, "no-pastml", pres_note) forms["past_m"] = stressed_past_stem .. (stressed_past_note or "") -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) return forms end conjugations["8b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local full_inf = get_stressed_arg(args, 2) local stem = get_unstressed_arg(args, 3) local stressed_past_stems = rsplit(args[4] or "ё", ",") for _, stressed_past_stem in ipairs(stressed_past_stems) do if stressed_past_stem ~= "е" then check_stressed_arg(stressed_past_stem, 4) end end no_stray_args(args, 4) forms["infinitive"] = full_inf local pres_note = class_8b_stem_to_infinitive(stem) ~= full_inf and IRREG local iotated_stem = com.iotation(stem) append_pres_futr(forms, iotated_stem, nil, {}, "ёшь", "ёт", "ём", "ёте", {}, pres_note) append_pres_futr(forms, stem, nil, "у́", {}, {}, {}, {}, "у́т", pres_note) append_imper(forms, stem, nil, "и́", "и́те", pres_note) -- set prefix to "" as stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, com.make_ending_stressed(stem), nil, args, data, "no-pastml", pres_note) forms["past_m"] = nil for _, stressed_past_stem in ipairs(stressed_past_stems) do local pastm_stem, past_part_stem if stressed_past_stem == "е" then past_part_stem = com.make_ending_stressed(stem) pastm_stem = past_part_stem elseif stressed_past_stem == "ё" then past_part_stem = convert_last_e_to_yo(com.make_ending_stressed(stem)) pastm_stem = past_part_stem elseif stressed_past_stem == "ёе" then past_part_stem = com.make_ending_stressed(stem) pastm_stem = convert_last_e_to_yo(past_part_stem) else pastm_stem = stressed_past_stem past_part_stem = stressed_past_stem end local past_note = class_8b_stem_to_infinitive(pastm_stem) ~= full_inf and IRREG -- default for pres_pasv_part is blank; влечь -> влеко́мый handled through -- general override mechanism append_participles_2stem(forms, stem, nil, past_part_stem, nil, "у́щий", "-", "-", "ший", "ши", "-", pres_note, past_note) append_form(forms, "past_m", pastm_stem, nil, "", past_note) end -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) return forms end conjugations["9a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "еть") local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) local default_pres_stem = prefix .. rsub(base, "е", "") pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem .. "еть" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "ший", "ши", "ев") present_e_a(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и", "ите", pres_note) -- past_m doesn't end in л set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data, "no-pastml") set_ppp_from_past_m(forms, args, data) return forms end conjugations["9b"] = function(args, data) local forms = {} --for this type, it's important to distinguish impf and pf local impf = rfind(data.verb_type, "^impf") parse_variants(data, args[1], {"past", "+p", "*"}) local stem_noa = com.strip_ending(get_stressed_arg(args, 2), nil, "е́ть") local stem = rsub(stem_noa, "(.*)е", "%1ё") local pres_stem = get_opt_unstressed_arg(args, 3) -- stem used for past active and adverbial participles; defaults to past_m local past_part_stem = get_opt_stressed_arg(args, 4) no_stray_args(args, 4) local prefix, _, base, _ = split_monosyllabic_main_verb(stem, nil, "single_cons_base") local default_pres_stem = data.star and construct_long_prefix_variant(prefix) .. rsub(base, "[её]", "") or prefix .. rsub(base, "[её]", "") pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem_noa .. "е́ть" present_e_b(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и́", "и́те", pres_note) -- past_m doesn't end in л set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data, "no-pastml") set_ppp_from_past_m(forms, args, data) append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", {}, {}, -- impf: тереть -> тёрши -- pf: растереть -> растёрши, растере́в -- we handle (рас)тёрши down below because the stress depends on the -- past_m: запереть -> за́пер, за́перши(й) {}, {}, impf and {} or "е́в", pres_note) if past_part_stem then for _, ppstem in ipairs(rsplit(past_part_stem, ",")) do append_participles(forms, ppstem, nil, {}, {}, {}, "ший", "ши", {}) end else iterate_over_prop(forms, args, "past_m", function(ru, tr, note) append_participles(forms, ru, tr, {}, {}, {}, "ший", "ши", {}, note) end) end return forms end conjugations["10a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "оть") no_stray_args(args, 2) forms["infinitive"] = stem .. "оть" -- These verbs are perfective-only, no present participles append_participles(forms, stem, nil, "-", "-", "-", "овший", "овши", "ов") set_moving_ppp(forms, data) present_je(forms, stem, nil, "a") append_imper(forms, stem, nil, "и", "ите") set_past(forms, stem .. "ол", nil, "", "а", "о", "и") return forms end conjugations["10c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7"}) local inf_stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") -- present tense stressed stem "моло́ть" - ме́лет local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = com.make_ending_stressed(com.strip_ending(inf_stem, nil, "о́")) pres_stem = pres_stem or default_pres_stem -- remove accent for some forms local pres_stem_noa = com.remove_accents(pres_stem) local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = inf_stem .. "ть" -- default for pres_pasv_part is blank append_participles_2stem(forms, pres_stem, nil, inf_stem, nil, "ющий", "-", "я́", "вший", "вши", "в", pres_note) set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "c", nil, pres_note) append_imper(forms, pres_stem_noa, nil, "и́", "и́те", pres_note) set_past(forms, inf_stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["11a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ить") no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem .. "и") forms["infinitive"] = stem .. "ить" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "ивший", "ивши", "ив") present_je(forms, stem .. "ь", nil, "a") append_imper(forms, stem .. "ей", nil, "", "те") set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["11b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p", "*"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "и́ть") local pres_stem = get_opt_unstressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem .. "и́", nil, "single_cons_base") local default_pres_stem = data.star and construct_long_prefix_variant(prefix) .. rsub(base, "и́$", "") or stem pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem .. "и́ть" append_participles_2stem(forms, pres_stem, nil, stem, nil, "ью́щий", "-", "ья́", "и́вший", "и́вши", "и́в", pres_note) present_je(forms, pres_stem .. "ь", nil, "b", nil, pres_note) append_imper(forms, stem .. "е́й", nil, "", "те") -- e.g. пила́, лила́ set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["12a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = stem pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" append_participles_2stem(forms, pres_stem, nil, stem, nil, "ющий", "емый", "я", "вший", "вши", "в", pres_note) present_je(forms, pres_stem, nil, "a", nil, pres_note) append_imper(forms, pres_stem .. "й", nil, "", "те", pres_note) set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["12b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_opt_unstressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = com.make_unstressed_once(stem) pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "ю́щий", "-", "я́", "вший", "вши", "в", pres_note) present_je(forms, pres_stem, nil, "b", nil, pres_note) -- the preceding vowel is stressed append_imper(forms, pres_stem .. "́й", nil, "", "те", pres_note) -- e.g. гнила́ but пе́ла set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["13b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = com.strip_ending(stem, nil, "ва́") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- tricky to use append_participles_2stem() because only pres_actv_part -- uses pres_stem, not all present participles forms["pres_actv_part"] = pres_stem .. "ю́щий" forms["pres_pasv_part"] = stem .. "емый" forms["pres_adv_part"] = stem .. "я" forms["past_actv_part"] = stem .. "вший" forms["past_adv_part"] = stem .. "вши" forms["past_adv_part_short"] = stem .. "в" set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "b") forms["impr_sg"] = stem .. "й" forms["impr_pl"] = stem .. "йте" set_past(forms, stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["14a"] = function(args, data) -- only one verb: вы́жать local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_stressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "вший", "вши", "в") present_e_a(forms, pres_stem) forms["impr_sg"] = pres_stem .. "и" forms["impr_pl"] = pres_stem .. "ите" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["14b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_unstressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_b(forms, pres_stem) forms["impr_sg"] = pres_stem .. "и́" forms["impr_pl"] = pres_stem .. "и́те" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["14c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_stressed_arg(args, 3) local pres_stem_noa = com.make_unstressed(pres_stem) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_c(forms, pres_stem) forms["impr_sg"] = pres_stem_noa .. "и́" forms["impr_pl"] = pres_stem_noa .. "и́те" --two forms for past_m: при́нялся, приня́лся --изъя́ла but приняла́ set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["15a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, stem, nil, "нущий", "-", "-", "вший", "вши", "в") present_e_a(forms, stem .. "н") forms["impr_sg"] = stem .. "нь" forms["impr_pl"] = stem .. "ньте" set_past(forms, stem .. "л", nil, "", "а", "о", "и") set_ppp_from_past_m(forms, args, data) return forms end conjugations["16a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, stem, nil, "ву́щий", "-", "-", "вший", "вши", "в") present_e_a(forms, stem .. "в") forms["impr_sg"] = stem .. "ви" forms["impr_pl"] = stem .. "вите" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["16b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = com.strip_ending(get_stressed_arg(args, 2), nil, "ть") local stem_noa = com.make_unstressed(stem) no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles(forms, stem, nil, "ву́щий", "-", "вя́", "вший", "вши", "в") present_e_b(forms, stem_noa .. "в") forms["impr_sg"] = stem_noa .. "ви́" forms["impr_pl"] = stem_noa .. "ви́те" -- e.g. прижило́сь, прижи́лось set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg"] = function(args, data) local main = select(3, split_known_main_verb(get_stressed_arg(args, 2), -- честь must go before есть {"бежа́ть", "бѣжа́ть", "хоте́ть", "хотѣ́ть", "да́ть", "че́сть", "е́сть", "ѣ́сть", "сы́пать", "лга́ть", "мо́чь", "идти́", "йти́", "е́хать", "ѣ́хать", "мину́ть", "живописа́ть", "ле́чь", "зи́ждить", "зы́бить", "кля́сть", "стели́ть", "бы́ть", "сса́ть", "сца́ть", "чти́ть", "шиби́ть", "реве́ть", "има́ть", "вня́ть", "обя́зывать"})) main = com.make_unstressed_once(main) if not conjugations["irreg-" .. main] then error("Strange, can't find conjugation for main verb " .. main) end return conjugations["irreg-" .. main](args, data) end conjugations["irreg-бежать"] = function(args, data) -- irregular, only for verbs derived from бежать with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"бежа́ть", "бѣжа́ть"}) data.title = com.is_stressed(prefix) and "5a" or "5b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "бежа́ть" append_participles_2stem(forms, "бег", nil, "бежа́", nil, "у́щий", "-", "-", "вший", "вши", "в", IRREG) append_imper(forms, "беги́", nil, "", "те", IRREG) append_pres_futr(forms, "бе", nil, "гу́" .. IRREG, "жи́шь", "жи́т", "жи́м", "жи́те", "гу́т" .. IRREG) set_past(forms, "бежа́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^бе", "бѣ") end prepend_prefix(forms, prefix) -- no PPP's for any derivatives of бежать return forms end conjugations["irreg-бѣжать"] = conjugations["irreg-бежать"] conjugations["irreg-хотеть"] = function(args, data) -- irregular, only for verbs derived from хотеть with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"хоте́ть", "хотѣ́ть"}) data.title = "5c'" data.cat_conj_types = {"5c"} -- no class for 5c', no point in creating for just this verb -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "хоте́ть" append_participles_2stem(forms, "хот", nil, "хоте́", nil, "я́щий", "-", "я́", "вший", "вши", "в") append_imper(forms, "хоти́", nil, "", "те") append_pres_futr(forms, "", nil, "хочу́", "хо́чешь" .. IRREG, "хо́чет" .. IRREG, "хоти́м", "хоти́те", "хотя́т") set_past(forms, "хоте́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^хоте", "хотѣ") end prepend_prefix(forms, prefix) return forms end conjugations["irreg-хотѣть"] = conjugations["irreg-хотеть"] conjugations["irreg-дать"] = function(args, data) -- irregular, only for verbs derived from дать with the same stress pattern and вы́дать local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "да́ть") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "да́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "", nil, "даю́щий", "-", "-", "да́вший", "да́вши", "да́в") append_imper(forms, "да́й", nil, "", "те") append_pres_futr(forms, "", nil, "да́м", "да́шь", "да́ст", "дади́м", "дади́те", "даду́т") prepend_prefix(forms, prefix) set_past_by_stress(forms, data.past_stress, prefix, nil, "да́", nil, args, data) if data.ppp then if prefix == "пере" then set_ppp(forms, "", nil, "пе́реданный") elseif prefix == "раз" then set_ppp(forms, "", nil, "ро́зданный") else set_moving_ppp(forms, data) end end return forms end conjugations["irreg-есть"] = function(args, data) -- irregular, only for verbs derived from есть local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"е́сть", "ѣ́сть"}) data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "е́сть" append_participles_2stem(forms, "ед", nil, "е́", nil, "я́щий", "о́мый", "я́", "вший", "вши", "в") if data.ppp then set_ppp(forms, "е́д", nil, "енный") end append_imper(forms, "е́шь", nil, "", "те") append_pres_futr(forms, "е́", nil, "м", "шь", "ст", "ди́м", "ди́те", "дя́т") set_past(forms, "е́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^е", "ѣ") end prepend_prefix(forms, prefix) return forms end conjugations["irreg-ѣсть"] = conjugations["irreg-есть"] conjugations["irreg-сыпать"] = function(args, data) -- irregular, only for verbs derived from сыпать local forms = {} --for this type, it's important to distinguish if it's reflexive for вы́сыпаться vs. вы́сыпать imperative local prefix = split_known_main_verb(get_stressed_arg(args, 2), "сы́пать") data.title = "6a" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "сы́пать" append_participles(forms, "сы́п", nil, "лющий", "лемый", {"ля", "я" .. IRREG}, "авший", "авши", "ав") append_imper(forms, "сы́п", nil, -- вы́сыпать (but not вы́сыпаться) has two imperative singulars com.is_stressed(prefix) and not data.refl and {"и", "ь"} or "ь", "ьте", IRREG) present_je(forms, "сы́пл", nil, "a") append_pres_futr(forms, "сы́п", nil, {}, "ешь", "ет", "ем", "ете", {}, IRREG) set_past(forms, "сы́пал", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-лгать"] = function(args, data) -- irregular, only for verbs derived from лгать with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "лга́ть") data.title = "6°b/c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "лга́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "лг", nil, "у́щий", "-", "-", "а́вший", "а́вши", "а́в") append_imper(forms, "лги́", nil, "", "те") append_pres_futr(forms, "", nil, "лгу́", "лжёшь" .. IRREG, "лжёт" .. IRREG, "лжём" .. IRREG, "лжёте" .. IRREG, "лгу́т") set_past(forms, "лга́л", nil, "", "а́", "о", "и") prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-мочь"] = function(args, data) -- irregular, only for verbs derived from мочь with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "мо́чь") data.title = "8c/b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "мо́чь" -- no passive or adverbial participles append_participles(forms, "мо́г", nil, "у́щий", "-", "-", "ший", "-", "-") append_imper(forms, "моги́", nil, "", "те") append_pres_futr(forms, "", nil, "могу́", "мо́жешь", "мо́жет", "мо́жем", "мо́жете", "мо́гут") set_past(forms, "мо́г", nil, "", "ла́", "ло́", "ли́") prepend_prefix(forms, prefix) return forms end conjugations["irreg-идти"] = function(args, data) -- irregular, only for verbs derived from идти, including прийти́ and в́ыйти local forms = {} local prefix = args[2] == "идти́" and "" or split_known_main_verb(get_stressed_arg(args, 2), "йти́") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b/b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no pres_pasv_part if prefix == "" then -- only идти, present imperfective forms["infinitive"] = "идти́" append_imper(forms, "иди́", nil, "", "те") present_e_b(forms, "ид") -- no past_adv_part_short append_participles(forms, "", nil, "иду́щий", "-", "идя́", "ше́дший", "ше́дши", "-") elseif rfind(prefix, "и$") then -- при forms["infinitive"] = "йти́" append_imper(forms, "ди́", nil, "", "те") present_e_b(forms, "д") append_participles(forms, "", nil, "-", "-", "-", "ше́дший", "ше́дши", "дя́") else forms["infinitive"] = "йти́" append_imper(forms, "йди́", nil, "", "те") present_e_b(forms, "йд") append_participles(forms, "", nil, "-", "-", "-", "ше́дший", "ше́дши", "йдя́") end set_past(forms, "", nil, "шёл", "шла́", "шло́", "шли́") prepend_prefix(forms, prefix) if data.ppp then if prefix == "на" or prefix == "про" then -- найти́ and пройти́ exceptionally have the stress on the prefix set_ppp(forms, prefix, nil, "́йденный") else -- вы́йти and прийти́ are intransitive so we don't have to worry about them set_ppp(forms, prefix, nil, "йдённый") end end return forms end conjugations["irreg-йти"] = conjugations["irreg-идти"] conjugations["irreg-ехать"] = function(args, data) -- irregular, only for verbs derived from ехать local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"е́хать", "ѣ́хать"}) data.title = "irreg-a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "е́хать" -- no pres_pasv_part -- no pres_adv_part append_participles_2stem(forms, "е́д", nil, "е́х", nil, "ущий", "-", "-", "авший", "авши", "ав") present_e_a(forms, "е́д") set_past(forms, "е́хал", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^е", "ѣ") end prepend_prefix(forms, prefix) --special-case the imperative --literary (special) imperative forms for ехать are поезжа́й, поезжа́йте local impstem = data.old and "ѣзжа́й" or "езжа́й" if prefix == "" then append_imper(forms, "по" .. impstem, nil, "", "те") append_imper(forms, impstem, nil, "", "те") elseif com.is_stressed(prefix) then append_imper(forms, com.make_unstressed_once(prefix) .. impstem, nil, "", "те") else append_imper(forms, prefix .. impstem, nil, "", "те") end return forms end conjugations["irreg-ѣхать"] = conjugations["irreg-ехать"] conjugations["irreg-минуть"] = function(args, data) -- for the irregular verb "мину́ть" local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "мину́ть") data.title = "3c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "мину́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "ми́н", nil, "у́щий", "-", "-", "у́вший", "у́вши", "у́в") present_e_c(forms, "ми́н") forms["pres_futr_1sg"] = "-" -- no futr 1sg -- no imperative -- two possible variants, one with root-only stress, the other with -- either root or suffix stress. if not args["root_past_stress"] then append_past(forms, "мину́л", nil, "", "а", "о", "и") end append_past(forms, "ми́нул", nil, "", "а", "о", "и", IRREG) prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-живописать"] = function(args, data) -- for irregular verb "живописа́ть", mixture of types 1 and 2 local forms = {} local inf = get_stressed_arg(args, 2) data.title = "1a" parse_variants(data, args[1], {"+p"}) local inf_stem = com.strip_ending(inf, nil, "ть") local pres_stem = rfind(inf_stem, "а́$") and rsub(inf_stem, "а́$", "у́") or error("Unexpected infinitive " .. inf) no_stray_args(args, 2) forms["infinitive"] = inf_stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, inf_stem, nil, "ющий", "-", "я", "вший", "вши", "в", IRREG) set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "a", nil, IRREG) append_imper(forms, pres_stem .. "й", nil, "", "те", IRREG) set_past(forms, inf_stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["irreg-лечь"] = function(args, data) -- irregular, only for verbs derived from лечь with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "ле́чь") data.title = "8a/b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "ле́чь" -- no pres parts because always perfective -- no past_adv_part_short append_participles(forms, "лёг", nil, "-", "-", "-", "ший", "ши", "-") append_imper(forms, "ля́г", nil, "", "те", IRREG) append_pres_futr(forms, "ля́", nil, "гу", "жешь", "жет", "жем", "жете", "гут", IRREG) set_past(forms, "", nil, "лёг", "легла́", "легло́", "легли́") prepend_prefix(forms, prefix) return forms end conjugations["irreg-честь"] = function(args, data) -- irregular, only for verbs derived from идти, including прийти́ and в́ыйти local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "че́сть") local pre_two_cons_prefix = prefix == "об" and "обо" or prefix == "с" and "со" or prefix == "рас" and "разо" or prefix data.title = prefix == "" and "7b/b" or com.is_stressed(prefix) and "7a⑨" or pre_two_cons_prefix ~= prefix and "7*b/b⑨" or "7b/b⑨" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no pres_pasv_part forms["infinitive"] = "че́сть" append_imper(forms, "чти́", nil, "", "те", IRREG) present_e_b(forms, "чт", nil, IRREG) if prefix == "" then append_participles(forms, "", nil, "чту́щий", "-", "чтя́", "чти́вший", "чти́вши", "чти́в", IRREG) elseif com.is_stressed(prefix) then append_participles(forms, "", nil, "-", "-", "-", "-", "чтя́", "-", IRREG) else append_participles(forms, "", nil, "-", "-", "-", "-", {"чтя́" .. IRREG, "чётши*"}, "-") m_table.insertIfNot(data.internal_notes, "* Dated.") end if data.ppp then set_ppp(forms, "", nil, "чтённый" .. IRREG) end set_past(forms, "", nil, "чёл", "чла́" .. IRREG, "чло́" .. IRREG, "чли́" .. IRREG) prepend_prefix(forms, prefix, pre_two_cons_prefix) return forms end conjugations["irreg-зиждить"] = function(args, data) -- irregular, only for verbs derived from зиждить(ся) with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "зи́ждить") data.title = "irreg-a" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "зи́ждить" append_participles(forms, "зи́жд", nil, "ущий", "емый", "я", "ивший", "ивши", "ив") if data.ppp then set_ppp(forms, "зи́жд", nil, "енный") end append_imper(forms, "зи́жди", nil, "", "те") present_e_a(forms, "зи́жд") set_past(forms, "зи́ждил", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-зыбить"] = function(args, data) -- irregular, only for verbs derived from зыбить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "зы́бить") data.title = "irreg-a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "зы́бить" append_participles(forms, "зы́б", nil, "лющий", "лемый", "ля", "ивший", "ивши", "ив") append_imper(forms, "зы́бли", nil, "", "те") present_je(forms, "зы́б", nil, "a") set_past(forms, "зы́бил", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-клясть"] = function(args, data) -- irregular, only for verbs derived from клясть with the same stress pattern local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "кля́сть") data.title = "irreg-b" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "кля́сть" append_participles_2stem(forms, "клян", nil, "кля́", nil, "у́щий", "и́мый", "я́", "вший", "вши", "в") append_imper(forms, "кляни́", nil, "", "те") present_e_b(forms, "клян") prepend_prefix(forms, prefix) set_past_by_stress(forms, data.past_stress, prefix, nil, "кля́", nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg-стелить"] = function(args, data) -- irregular, only for verbs derived from стелить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "стели́ть") data.title = com.is_stressed(prefix) and "4a" or "4c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "стели́ть" append_participles(forms, "сте́л", nil, "ющий" .. IRREG, "и́мый", "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, "сте́л", nil, data.title) append_imper(forms, "стели́", nil, "", "те") append_pres_futr(forms, "сте́л", nil, "ю́", {}, {}, {}, {}, {}) append_pres_futr(forms, "сте́л", nil, {}, "ешь", "ет", "ем", "ете", "ют", IRREG) set_past(forms, "стели́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-быть"] = function(args, data) -- irregular, only for verbs derived from быть with various stress patterns, the actual verb быть different from its derivatives local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "бы́ть") data.title = "irreg-a" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "бы́ть" -- no pres_pasv_part append_participles(forms, "", nil, "су́щий", "-", "бу́дучи", "бы́вший", "бы́вши", "бы́в") append_imper(forms, "бу́дь", nil, "", "те") prepend_prefix(forms, prefix) -- only for "бы́ть", some forms are archaic if forms["infinitive"] == "бы́ть" then append_pres_futr(forms, "", nil, "есть", "есть", "есть", "есть", "есть", "есть") elseif com.is_stressed(prefix) then -- if the prefix is stressed, e.g. "вы́быть" present_e_a(forms, prefix .. "буд") else present_e_a(forms, prefix .. "бу́д") end set_past_by_stress(forms, data.past_stress, prefix, nil, "бы́", nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg-ссать-сцать"] = function(args, data) -- irregular, only for verbs derived from ссать and сцать (both vulgar!) local forms = {} local prefix, _, stem = split_known_main_verb(get_stressed_arg(args, 2), {"сса́ть", "сца́ть"}) data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) stem = com.strip_ending(stem, nil, "ть") local pres_stem = rsub(stem, "а́?$", "") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, pres_stem, nil, "у́щий", "-", "-", "а́вший", "а́вши", "а́в") append_imper(forms, pres_stem, nil, "ы́", "ы́те") append_pres_futr(forms, pres_stem, nil, "у́", "ы́шь", "ы́т", "ы́м", "ы́те", "у́т") set_past(forms, stem .. "л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-ссать"] = conjugations["irreg-ссать-сцать"] conjugations["irreg-сцать"] = conjugations["irreg-ссать-сцать"] conjugations["irreg-чтить"] = function(args, data) -- irregular, only for verbs derived from чтить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "чти́ть") data.title = "4b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "чти́ть" append_participles_2stem(forms, "чт", nil, "чти́", nil, {"я́щий", "у́щий" .. IRREG}, "и́мый", "я́", "вший", "вши", "в") if data.ppp then set_ppp(forms, "чт", nil, "ённый") end append_imper(forms, "чти́", nil, "", "те") append_pres_futr(forms, "чт", nil, "у́" .. IRREG, "и́шь", "и́т", "и́м", "и́те", {"я́т", "у́т" .. IRREG}) set_past(forms, "чти́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-шибить"] = function(args, data) -- irregular, only for verbs in -шибить(ся) local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "шиби́ть") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no present participles forms["infinitive"] = "шиби́ть" append_participles(forms, "шиби́", nil, "-", "-", "-", "вший", "вши", "в") if data.ppp then set_ppp(forms, "ши́бл", nil, "енный") end append_imper(forms, "шиби́", nil, "", "те") present_e_b(forms, "шиб") set_past(forms, "ши́б", nil, "", "ла", "ло", "ли") prepend_prefix(forms, prefix) return forms end conjugations["irreg-реветь"] = function(args, data) -- irregular, only for verbs derived from "реветь" local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "реве́ть") data.title = "irreg-b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "реве́ть" -- no pres_pasv_part append_participles_2stem(forms, "рев", nil, "реве́", nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_b(forms, "рев") append_imper(forms, "реви́", nil, "", "те") set_past(forms, "реве́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-имать"] = function(args, data) -- irregular, only for внимать and certain archaic verbs (e.g. имать as -- conjugated in the 18th century, отъимать) local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "има́ть") data.title = "1a // 6a" data.cat_conj_types = {"1a", "6a"} parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "има́ть" -- handle внемл- forms append_participles(forms, "е́мл", nil, "ющий", "емый", {"я", "я́"}, {}, {}, {}) -- handle внима́- forms append_participles(forms, "има́", nil, "ющий", "емый", "я", "вший", "вши", "в") if data.ppp then -- FIXME, do class-1a-type ppp's (e.g. вни́манный) exist? -- ruwikt marks them with a * set_ppp(forms, "е́мл", nil, "енный") end append_imper(forms, "", nil, {"е́мли", "емли́", "има́й"}, {"е́млите", "емли́те", "има́йте"}) present_je(forms, "е́мл", nil, "a") -- Both вне́млю and внемлю́ are possible append_pres_futr(forms, "емл", nil, "ю́", {}, {}, {}, {}, {}) present_je(forms, "има́", nil, "a") set_past(forms, "има́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-внять"] = function(args, data) -- irregular, only for внять local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "вня́ть") data.title = "14c/c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "вня́ть" -- perfective only; no present participles append_participles(forms, "вня́", nil, "-", "-", "-", "вший", "вши", "в") append_imper(forms, "вними́", nil, "", "те") append_imper(forms, "вонми́", nil, "", "те") present_e_c(forms, "вни́м") present_e_c(forms, "во́нм") set_past(forms, "вня́л", nil, "", "а́", "о", "и") set_ppp_from_past_m(forms, args, data) prepend_prefix(forms, prefix) return forms end conjugations["irreg-обязывать"] = function(args, data) -- irregular, only for обязывать and обязываться local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "обя́зывать") data.title = "1a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "обя́зывать" append_participles_2stem(forms, "обя́з", nil, "обя́зыва", nil, {"ывающий", "у́ющий"}, {"ываемый", "у́емый"}, {"ывая", "у́я"}, "вший", "вши", "в") append_imper(forms, "обя́зывай", nil, "", "те") append_imper(forms, "обязу́й", nil, "", "те") present_je(forms, "обя́зыва", nil, "a") present_je(forms, "обязу́", nil, "a") set_past(forms, "обя́зывал", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end --[=[ Partial conjugation functions ]=] -- Present forms with -e-, no j-vowels. present_e_a = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у", "ешь", "ет", "ем", "ете", "ут", note) end present_e_b = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у́", "ёшь", "ёт", "ём", "ёте", "у́т", note) end present_e_c = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у́", "ешь", "ет", "ем", "ете", "ут", note) end -- Present forms with -e- and iotated stem. ABC = "a", "b" or "c", indicating -- the accent pattern. If SHCH is set, iotate final т as щ, not ч. If NOTE -- is given, add it to each form. present_je = function(forms, stem, tr, abc, shch, note) local iotated_stem, iotated_tr = com.iotation(stem, tr, shch) assert(abc == "a" or abc == "b" or abc == "c") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") -- or no_iotation local ending_1sg = hushing and (abc == "a" and "у" or "у́") or not hushing and (abc == "a" and "ю" or "ю́") if abc == "b" then append_pres_futr(forms, iotated_stem, iotated_tr, {}, "ёшь", "ёт", "ём", "ёте", (hushing and "у́т" or "ю́т"), note) else append_pres_futr(forms, iotated_stem, iotated_tr, {}, "ешь", "ет", "ем", "ете", (hushing and "ут" or "ют"), note) end append_pres_futr(forms, iotated_stem, iotated_tr, ending_1sg, {}, {}, {}, {}, {}, note) end -- Present forms with -i- (and iotated stem in the 1sg). ABC = "a", "b" or "c", -- indicating the accent pattern. If SHCH is set, iotate final т as щ, not ч. -- If NOTE is given, add it to each form. present_i = function(forms, stem, tr, abc, shch, note) local iotated_stem, iotated_tr = com.iotation(stem, tr, shch) assert(abc == "a" or abc == "b" or abc == "c") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local iotated_hushing = rfind(iotated_stem, "[шщжч]$") local hushing = rfind(stem, "[шщжч]$") local ending_1sg = iotated_hushing and (abc == "a" and "у" or "у́") or not iotated_hushing and (abc == "a" and "ю" or "ю́") if abc == "b" then append_pres_futr(forms, stem, tr, {}, "и́шь", "и́т", "и́м", "и́те", hushing and "а́т" or "я́т", note) else append_pres_futr(forms, stem, tr, {}, "ишь", "ит", "им", "ите", hushing and "ат" or "ят", note) end append_pres_futr(forms, iotated_stem, iotated_tr, ending_1sg, {}, {}, {}, {}, {}, note) end -- Add the reflexive particle to all verb forms make_reflexive = function(forms, reflex_stress) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) end if is_vowel_stem(ruentry) then forms[key] = {ruentry .. "сь" .. runotes, trentry and trentry .. "sʹ" .. trnotes} -- if a past_m form doesn't contain a stress, add a stressed -- particle "ся́" if called for elseif reflex_stress and com.is_unstressed(ruentry) and rfind(key, "^past_m") then forms[key] = {ruentry .. "ся́" .. runotes, trentry and trentry .. "sja" .. AC .. trnotes} else forms[key] = {ruentry .. "ся" .. runotes, trentry and trentry .. "sja" .. trnotes} end end end end -- Convert verb forms to pre-reform style by adding ъ to consonant-final -- forms (excluding those ending in й and ь) and converting -ий to -ій and -- -ийся to -ійся make_pre_reform = function(forms) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) if rfind(ruentry, "[бцдфгчклмнпрствшхзжщ]$") then forms[key] = {ruentry .. "ъ" .. runotes, tr} else forms[key] = {rsub(rsub(ruentry, "ий$", "ій"), "ийся$", "ійся") .. runotes, tr} end end end end local function setup_pres_futr(forms, perf, old) -- Copy the main form FROMFORM to the main form TOFORM, and copy all -- associated alternative forms. local function copy_form(fromform, toform) local fromforms = main_to_all_verb_forms[fromform] local toforms = main_to_all_verb_forms[toform] local numforms = #fromforms assert(#toforms == numforms) for i=1,numforms do forms[toforms[i]] = forms[fromforms[i]] end end -- Copy pres_futr_* to pres_* (imperfective) or futr_* (perfective). if perf then copy_form("pres_futr_1sg", "futr_1sg") copy_form("pres_futr_2sg", "futr_2sg") copy_form("pres_futr_3sg", "futr_3sg") copy_form("pres_futr_1pl", "futr_1pl") copy_form("pres_futr_2pl", "futr_2pl") copy_form("pres_futr_3pl", "futr_3pl") else copy_form("pres_futr_1sg", "pres_1sg") copy_form("pres_futr_2sg", "pres_2sg") copy_form("pres_futr_3sg", "pres_3sg") copy_form("pres_futr_1pl", "pres_1pl") copy_form("pres_futr_2pl", "pres_2pl") copy_form("pres_futr_3pl", "pres_3pl") end local futr_data = { {"futr_1sg", "бу́ду", "búdu"}, {"futr_2sg", "бу́дешь", "búdešʹ"}, {"futr_3sg", "бу́дет" .. (old and "ъ" or ""), "búdet"}, {"futr_1pl", "бу́дем" .. (old and "ъ" or ""), "búdem"}, {"futr_2pl", "бу́дете", "búdete"}, {"futr_3pl", "бу́дут" .. (old and "ъ" or ""), "búdut"} } local function insert_future(inf, inf_tr) for _, fut in ipairs(futr_data) do append_to_arg_chain(forms, fut[1], fut[1], {fut[2] .. inf, inf_tr and fut[3] .. inf_tr}) end end -- Insert future, if required (there may conceivably be multiple infitives). for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local infinitive = forms[form] if infinitive then local inf, inf_tr = extract_russian_tr(forms[form]) -- only for "бы́ть" the future forms are бу́ду, бу́дешь, etc. if inf == "бы́ть" then insert_future("", nil) elseif not perf then insert_future(" " .. inf, inf_tr and " " .. inf_tr) end end end end parse_and_stress_override = function(form, val, existing, all_existing) if rfind(form, "^pres_futr") then error("Overrides of pres_futr* are illegal, use pres_* or futr_*") end local allow_unaccented val, allow_unaccented = rsubb(val, "^%*", "") local ru, tr = com.split_russian_tr(val) -- past_m can be unaccented in connection with reflex_stress=ся́ if not allow_unaccented and not rfind(form, "^past_m") then if tr and com.is_unstressed(ru) ~= com.is_unstressed(tr) then error("Override " .. form .. "=" .. ru .. " and translit " .. tr .. " must have same accent pattern") end if com.is_monosyllabic(ru) then ru, tr = com.make_ending_stressed(ru, tr) elseif com.needs_accents(ru) then error("Override " .. form .. "=" .. ru .. " requires an accent") end end if rfind(ru, "%+") then -- If either the existing or override has manual translit, the resulting -- form should have manual translit. We specify ALWAYS_TRANSLIT if -- the override has manual translit, so that we can substitute the -- existing translit into the override translit. local existing_ru, existing_tr = extract_russian_tr(existing, not not tr) -- used especially for present participles; substitute existing form, -- minus any "awkward-" or "none-" prefixes. ru = rsub(ru, "%+", strip_arg_status_prefix(existing_ru)) -- If there's existing translit but not in the override, make sure it's -- carried along. if existing_tr and not tr then tr = com.translit(ru) end tr = tr and rsub(tr, "%+", strip_arg_status_prefix(existing_tr)) end -- If there's an override and it doesn't match an existing form, it's -- irregular and indicate it using the IRREG marker. We don't do this if -- the override simply removes a form. We do do this if there aren't any -- existing forms, on the theory that the presence of a form when none is -- normally called for is an irregularity. When comparing against the -- existing forms, strip any status prefix (e.g. 'awkward-'). if all_existing then local all_existing_stripped = {} for _, ae in ipairs(all_existing) do local existing_ru, existing_tr = extract_russian_tr(ae) existing_ru = strip_arg_status_prefix(existing_ru) existing_tr = existing_tr and strip_arg_status_prefix(existing_tr) table.insert(all_existing_stripped, {existing_ru, existing_tr}) end if ru ~= "-" and not contains_form(all_existing_stripped, {ru, tr}) then ru = ru .. IRREG tr = tr and tr .. IRREG end end return {ru, tr} end -- Set up pres_* or futr_*; handle *sym/*tail/*tailall notes and overrides. handle_forms_and_overrides = function(args, forms, data) setup_pres_futr(forms, data.perf, data.old) --handle overrides (formerly we only had past_pasv_part as a --general override, plus scattered main-form overrides in particular --conjugation classes) for _, all_forms in pairs(main_to_all_verb_forms) do local i = 0 local orig_forms = {} for _, form in ipairs(all_forms) do if forms[form] then table.insert(orig_forms, forms[form]) end end for _, form in ipairs(all_forms) do i = i + 1 -- If we auto-generated the past passive participle in order to -- check for irregular overrides, make sure to erase any such -- participles that weren't overridden. This happens for example -- in обнять, where there are two automatically generated past -- passive participles but a single ppp=о́внятый override. local override = args[form] or ( data.ppp_auto_generated and rfind(form, "^past_pasv_part") and "-" ) if override then forms[form] = parse_and_stress_override(form, override, forms[form], orig_forms) elseif i == 1 then forms[form] = forms[form] or "" end end end local function append_value(forms, prop, value) if forms[prop] and forms[prop] ~= "" and forms[prop] ~= "-" then value = com.split_russian_tr(value, "dopair") local curval = forms[prop] if type(curval) == "string" then curval = {curval} end forms[prop] = com.concat_paired_russian_tr(curval, value) end end local function append_note_all(forms, proplist, value) for _, prop in ipairs(proplist) do append_value(forms, prop, value) end end local function append_note_last(forms, proplist, value, gt_one) local numprops = 0 local lastprop -- Find the last property in the series with a value for _, prop in ipairs(proplist) do if forms[prop] and forms[prop] ~= "" and forms[prop] ~= "-" then numprops = numprops + 1 lastprop = prop end end if numprops > (gt_one and 1 or 0) then append_value(forms, lastprop, value) end end for _, proplist in ipairs(all_verb_forms) do -- Handle PROP_sym, which applies to all overridable properties, including -- alternative forms, and applies to exactly that property. for _, prop in ipairs(proplist) do if args[prop .. "_sym"] then append_value(forms, prop, args[prop .. "_sym"]) end end local propname = proplist[1] -- Handle PROP_tail, which applies to a series of properties (e.g. past_m, -- past_m2, ...) and appends to the last one. if args[propname .. "_tail"] then append_note_last(forms, proplist, args[propname .. "_tail"]) end -- Handle PROP_tailall, which applies to a series of properties and -- appends to all. if args[propname .. "_tailall"] then append_note_all(forms, proplist, args[propname .. "_tailall"]) end end -- Now handle pasttail, pasttailall, prestail, prestailall, etc. -- Table listing tail-arg prefix and corresponding verb forms. local tailargs = { {"past", past_verb_forms}, {"pres", pres_verb_forms}, {"futr", futr_verb_forms}, {"impr", impr_verb_forms}, {"part", part_verb_forms}, {"prespart", pres_part_verb_forms}, {"pastpart", past_part_verb_forms}, {"", all_main_verb_forms} } for _, tailspec in ipairs(tailargs) do local tailforms = tailspec[2] -- Handle the ...tail variants. local tailarg = tailspec[1] .. "tail" if args[tailarg] then track(tailarg) for _, prop in ipairs(tailforms) do append_note_last(forms, main_to_all_verb_forms[prop], args[tailarg], ">1") end end -- Handle the ...tailall variants. local tailallarg = tailspec[1] .. "tailall" if args[tailallarg] then track(tailallarg) for _, prop in ipairs(tailforms) do append_note_all(forms, main_to_all_verb_forms[prop], args[tailallarg]) end end end end -- Finish generating the forms; primarily, clear out unused forms. finish_generating_forms = function(forms, data) -- Convert any main form that's nil (meaning no forms at all corresponding -- to this main form) to the empty string. for main_form, _ in pairs(main_to_all_verb_forms) do if not forms[main_form] then forms[main_form] = "" end end -- Set the main form FORM to the empty string, and corresponding alt forms -- to nil. local function clear_form(form) local i = 0 for _, altform in ipairs(main_to_all_verb_forms[form]) do i = i + 1 if i == 1 then forms[altform] = "" else forms[altform] = nil end end end -- Intransitive and reflexive verbs have no passive participles -- (unless has_prpp=y and/or has_ppp=y). if data.intr or data.refl then if not data.has_prpp then clear_form("pres_pasv_part") end if not data.has_ppp then clear_form("past_pasv_part") end end if data.refl then -- no past_adv_part_short for reflexive verbs clear_form("past_adv_part_short") end -- Impersonal verbs normally have no passive participles, but allow them -- if there's specifically an override. We only do this for the present -- passive participle because the past passive participle isn't inserted -- by default, and we still want +p to work, which doesn't currently set -- data.ppp_override. if data.impers and not data.prpp_override then clear_form("pres_pasv_part") end if data.impers then clear_form("pres_1sg") clear_form("pres_2sg") clear_form("pres_1pl") clear_form("pres_2pl") clear_form("pres_3pl") clear_form("futr_1sg") clear_form("futr_2sg") clear_form("futr_1pl") clear_form("futr_2pl") clear_form("futr_3pl") clear_form("past_m") clear_form("past_f") clear_form("past_pl") clear_form("past_m_short") clear_form("past_f_short") clear_form("past_pl_short") clear_form("pres_actv_part") clear_form("past_actv_part") clear_form("pres_adv_part") clear_form("past_adv_part") clear_form("past_adv_part_short") clear_form("impr_sg") clear_form("impr_pl") end -- Perfective and iterative verbs have no present forms, as well as -- verbs marked nopres=1. if data.perf or data.iter or data.nopres then clear_form("pres_actv_part") clear_form("pres_pasv_part") clear_form("pres_adv_part") clear_form("pres_1sg") clear_form("pres_2sg") clear_form("pres_3sg") clear_form("pres_1pl") clear_form("pres_2pl") clear_form("pres_3pl") end -- Some verbs (e.g. грясти́, густи́) have no past if data.nopast then clear_form("past_m") clear_form("past_f") clear_form("past_n") clear_form("past_pl") clear_form("past_m_short") clear_form("past_f_short") clear_form("past_n_short") clear_form("past_pl_short") clear_form("past_actv_part") clear_form("past_pasv_part") clear_form("past_adv_part") clear_form("past_adv_part_short") end -- Iterative verbs and verbs marked noimpr=1 have no imperative forms. if data.iter or data.noimpr then clear_form("impr_sg") clear_form("impr_pl") end -- Iterative verbs and verbs marked nofutr=1 have no future forms. if data.iter or data.nofutr then clear_form("futr_1sg") clear_form("futr_2sg") clear_form("futr_3sg") clear_form("futr_1pl") clear_form("futr_2pl") clear_form("futr_3pl") end --handle "none-" and "awkward-" prefixes (used especially for pres_pasv_part) local footnote_sym = nil for _, all_forms in pairs(main_to_all_verb_forms) do local i = 0 for _, form in ipairs(all_forms) do i = i + 1 if forms[form] then local formru, formtr = extract_russian_tr(forms[form]) if rfind(formru, "^none%-") then if i == 1 then forms[form] = "" else forms[form] = nil end elseif rfind(formru, "^awkward%-") then if not footnote_sym then footnote_sym = next_note_symbol(data) m_table.insertIfNot(data.internal_notes, footnote_sym .. " Rare and awkward.") end forms[form] = {rsub(formru, "^awkward%-", "") .. footnote_sym, formtr and rsub(formtr, "^awkward%-", "") .. footnote_sym} end end end end --Insert footnote for IRREG symbol if present. for _, all_forms in pairs(main_to_all_verb_forms) do for _, form in ipairs(all_forms) do if forms[form] then local formru = extract_russian_tr(forms[form]) if rfind(formru, IRREG) then m_table.insertIfNot(data.internal_notes, IRREG .. " Irregular.") end end end end end local accel_forms = { -- present tense pres_1sg = "1|s|pres|ind", pres_2sg = "2|s|pres|ind", pres_3sg = "3|s|pres|ind", pres_1pl = "1|p|pres|ind", pres_2pl = "2|p|pres|ind", pres_3pl = "3|p|pres|ind", -- future tense futr_1sg = "1|s|fut|ind", futr_2sg = "2|s|fut|ind", futr_3sg = "3|s|fut|ind", futr_1pl = "1|p|fut|ind", futr_2pl = "2|p|fut|ind", futr_3pl = "3|p|fut|ind", -- imperative impr_sg = "2|s|imp", impr_pl = "2|p|imp", -- past past_m = "m|s|past|ind", past_f = "f|s|past|ind", past_n = "n|s|past|ind", past_pl = "p|past|ind", past_m_short = "short|m|s|past|ind", past_f_short = "short|f|s|past|ind", past_n_short = "short|n|s|past|ind", past_pl_short = "short|p|past|ind", -- active participles pres_actv_part = "pres|act|part", past_actv_part = "past|act|part", -- passive participles pres_pasv_part = "pres|pass|part", past_pasv_part = "past|pass|part", -- adverbial participles pres_adv_part = "pres|adv|part", past_adv_part = "past|adv|part", past_adv_part_short = "short|past|adv|part", -- infinitive infinitive = "inf", } -- Make the table make_table = function(forms, title, perf, intr, impers, notes, internal_notes, old) local infinitives = {} for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local infinitive = forms[form] if infinitive then local inf = extract_russian_tr(forms[form]) if inf ~= "-" then m_table.insertIfNot(infinitives, inf) end end end -- Group forms together for a given key and combine adjacent forms with the same -- Russian (they should always have different translits). Take care not to introduce -- manual translit unnecessarily. local grouped_forms = {} for dispform, sourceforms in pairs(disp_verb_form_map) do local entry = {} for _, form in ipairs(sourceforms) do local ru, tr = extract_russian_tr(forms[form]) -- check for empty strings, dashes and nil's if ru and ru ~= "" and ru ~= "-" and ru ~= "&mdash;" then if #entry > 0 then local lastru, lasttr = extract_russian_tr(entry[#entry]) if lastru == ru then if not lasttr and not tr or lasttr == tr then error("Russian form " .. ru .. " is duplicated, probably due to a duplicative override") end lasttr = lasttr or com.translit(lastru) tr = tr or com.translit(ru) entry[#entry] = {ru, lasttr .. " ''or'' " .. tr} else table.insert(entry, {ru, tr}) end else table.insert(entry, {ru, tr}) end end end grouped_forms[dispform] = entry end local title = (old and "Pre-reform conjugation" or "Conjugation") .. (#infinitives == 0 and "" or " of <span lang=\"ru\" class=\"Cyrl\">''" .. table.concat(infinitives, ", ") .. "''</span>") .. (title and " (" .. title .. ")" or "") local function add_links(ru, rusuf, runotes, tr, trnotes, accel) local ruspan ruspan = m_links.full_link({lang = lang, term = ru, accel = accel, tr = "-"}) if rusuf ~= "" then rusuf = "<span lang=\"ru\" class=\"Cyrl\">" .. rusuf .. "</span>" end return ruspan .. rusuf .. runotes .. "<br/>" .. require("Modül:alfabe araçları").tag_translit(tr .. trnotes, lang, "default", 'style="color:var(--wikt-palette-grey-8,#888);"') end -- NOTE: No need to check for multiple infinitives because the accel system -- doesn't support multiple lemmas. local lemma, lemmatr = extract_russian_tr(forms["infinitive"]) -- check for empty strings, dashes and nil's if lemma and lemma ~= "" and lemma ~= "-" and lemma ~= "&mdash;" then lemma = m_table_tools.separate_notes(lemma) if lemmatr then lemmatr = m_table_tools.separate_notes(lemmatr) end else -- In case the lemma is an empty string or dash, set to nil so we don't -- set a lemma in the accelerator and fall back to the page name. lemma = nil lemmatr = nil end -- Convert to displayed form local disp = {} for key, entry in pairs(grouped_forms) do for i, form in ipairs(entry) do local ru, origtr = extract_russian_tr(form) local tr = origtr or ru and com.translit(ru) local ruentry, runotes = m_table_tools.get_notes(ru) local trentry, trnotes = m_table_tools.get_notes(tr) local accel_form = accel_forms[key] if not accel_form then error("Unrecognized key " .. key .. " when looking up accelerator form") end local accel if origtr and origtr:find(" ''or'' ") then -- Multiple translits for a given Russian term. -- FIXME! Support this. accel = nil else accel = { form = accel_form, translit = origtr, lemma = lemma, lemma_translit = lemmatr} end if rfind(key, "^futr") then -- Add link to first word (form of 'to be') local tobe, inf = rmatch(ruentry, "^([^ ]*) ([^ ]*)$") if tobe then -- No accelerators for imperfective future, as it's just the future of "to be" -- plus the infinitive. entry[i] = add_links(tobe, " " .. inf, runotes, trentry, trnotes, nil) else entry[i] = add_links(ruentry, "", runotes, trentry, trnotes, accel) end else entry[i] = add_links(ruentry, "", runotes, trentry, trnotes, accel) end end disp[key] = table.concat(entry, ",<br/>") if disp[key] == "" then disp[key] = "&mdash;" end end local all_notes = {} for _, note in ipairs(internal_notes) do local symbol, entry = m_table_tools.get_initial_notes(note) table.insert(all_notes, symbol .. entry) end for _, note in ipairs(notes) do local symbol, entry = m_table_tools.get_initial_notes(note) table.insert(all_notes, symbol .. entry) end local notes_text table.insert(all_notes, 1, "Note: For declension of participles, see their entries. Adverbial participles are indeclinable.") notes_text = table.concat(all_notes, "<br />") .. "\n" return [=[<div class="NavFrame" style="max-width:49.6em;"> <div class="NavHead" style="text-align:left; background:var(--wikt-palette-lightindigo, #e9e9ff);">]=] .. title .. [=[</div> <div class="NavContent"> {| class="inflection inflection-ru inflection-verb inflection-table" |+ ]=] .. notes_text .. [=[ |- class="rowgroup" ! colspan="3" | ]=] .. (perf and [=[[[совершенный вид|perfective aspect]]]=] or [=[[[несовершенный вид|imperfective aspect]]]=]) .. [=[ |- ! [[неопределённая форма|infinitive]] | colspan="2" | ]=] .. disp.infinitive .. [=[ |- class="rowgroup" ! style="width:15em" | [[причастие|participles]] ! [[настоящее время|present tense]] ! [[прошедшее время|past tense]] |- ! [[действительный залог|active]] | ]=] .. disp.pres_actv_part .. [=[ || ]=] .. disp.past_actv_part .. [=[ |- ! [[страдательный залог|passive]] | ]=] .. disp.pres_pasv_part .. [=[ || ]=] .. disp.past_pasv_part .. [=[ |- ! [[деепричастие|adverbial]] | ]=] .. disp.pres_adv_part .. [=[ || ]=] .. disp.past_adv_part .. [=[ |- class="rowgroup" ! ! [[настоящее время|present tense]] ! [[будущее время|future tense]] |- ! [[первое лицо|1st]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">я</span>) | ]=] .. disp.pres_1sg .. [=[ || ]=] .. disp.futr_1sg .. [=[ |- ! [[второе лицо|2nd]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">ты</span>) | ]=] .. disp.pres_2sg .. [=[ || ]=] .. disp.futr_2sg .. [=[ |- ! [[третье лицо|3rd]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">он/она́/оно́</span>) | ]=] .. disp.pres_3sg .. [=[ || ]=] .. disp.futr_3sg .. [=[ |- ! [[первое лицо|1st]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">мы</span>) | ]=] .. disp.pres_1pl .. [=[ || ]=] .. disp.futr_1pl .. [=[ |- ! [[второе лицо|2nd]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">вы</span>) | ]=] .. disp.pres_2pl .. [=[ || ]=] .. disp.futr_2pl .. [=[ |- ! [[третье лицо|3rd]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">они́</span>) | ]=] .. disp.pres_3pl .. [=[ || ]=] .. disp.futr_3pl .. [=[ |- class="rowgroup" ! [[повелительное наклонение|imperative]] ! [[единственное число|singular]] ! [[множественное число|plural]] |- ! [[второе лицо|2nd]] (<span lang="ru" class="Cyrl">ты/вы</span>) | ]=] .. disp.impr_sg .. [=[ || ]=] .. disp.impr_pl .. [=[ |- class="rowgroup" ! [[прошедшее время|past tense]] ! [[единственное число|singular]] ! [[множественное число|plural]]<br/>(<span lang="ru" class="Cyrl">мы/вы/они́</span>) |- ! [[мужской род|masculine]] (<span lang="ru" class="Cyrl">я/ты/он</span>) | ]=] .. disp.past_m .. [=[ || rowspan="3" | ]=] .. disp.past_pl .. [=[ |- ! [[женский род|feminine]] (<span lang="ru" class="Cyrl">я/ты/она́</span>) | ]=] .. disp.past_f .. [=[ |- ! [[средний род|neuter]] (<span lang="ru" class="Cyrl">оно́</span>) | ]=] .. disp.past_n .. [=[ |} </div> </div>]=] end return export bd3o6mk40k4u7jwiwyfznuax009lqb8 Modül:User:Benwing2/ru-verb 828 1591007 5672500 2026-06-29T15:10:53Z MustafaCavlak 59368 imported from en 5672500 Scribunto text/plain --[=[ This module contains functions for creating inflection tables for Russian verbs. Author: Benwing, rewritten from early version by Atitarev, earliest version by CodeCat NOTE: This module is partly converted to support manual translit, in the form CYRILLIC//LATIN (i.e. with a // separating the Cyrillic and Latin parts). All the general infrastructure supports manual translit; the only thing that doesn't is some of the specific verb conjugation functions. In particular, all of the class 1, 2, 3 and 4 conjugation functions support manual translit, and the rest don't. To convert another, follow the model of one of the already-converted functions. Note that an individual form (an entry in the 'forms' table) can be either a string (no special manual translit; generally this originates from the portion of the code that doesn't support manual translit), or a one-element list {CYRILLIC} (no special manual translit), or a two-element list {CYRILLIC, LATIN} with manual translit specified. The code is careful only to generate manual translit when it's needed, to avoid penalizing the majority of cases where manual transit isn't needed. ]=] local m_utilities = require("Module:utilities") local ut = require("Module:utils") local m_links = require("Module:links") local com = require("Module:ru-common") local nom = require("Module:ru-nominal") local m_debug = require("Module:debug") local m_table_tools = require("Module:table tools") -- If enabled, compare this module with new version of module to make -- sure all conjugations are the same. local test_new_ru_verb_module = false local export = {} -- Within this module, conjugations are the functions that do the actual -- conjugating by creating the forms of a basic verb. -- They are defined further down. local conjugations = {} local lang = require("Module:languages").getByCode("ru") local u = mw.ustring.char local rfind = mw.ustring.find local rsubn = mw.ustring.gsub local rmatch = mw.ustring.match local rsplit = mw.text.split local usub = mw.ustring.sub local AC = u(0x0301) -- acute = ́ local DIA = u(0x0308) -- diaeresis = ̈ local PSEUDOCONS = u(0xFFF2) -- pseudoconsonant placeholder, matching ru-common local IRREG = "△" -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end -- version of rsubn() that returns a 2nd argument boolean indicating whether -- a substitution was made. local function rsubb(term, foo, bar) local retval, nsubs = rsubn(term, foo, bar) return retval, nsubs > 0 end -- Fancy version of ine() (if-not-empty). Converts empty string to nil, -- but also strips leading/trailing space and then single or double quotes, -- to allow for embedded spaces. local function ine(arg) if not arg then return nil end arg = rsub(arg, "^%s*(.-)%s*$", "%1") if arg == "" then return nil end local inside_quotes = rmatch(arg, '^"(.*)"$') if inside_quotes then return inside_quotes end inside_quotes = rmatch(arg, "^'(.*)'$") if inside_quotes then return inside_quotes end return arg end local function is_vowel_stem(stem) return rfind(stem, "[" .. com.vowel .. AC .. DIA .. "]$") end -- Return the next number to use as an internal note symbol, starting at 1. -- We look at existing internal notes to see if the symbol is already used. local function next_note_symbol(data) local nextsym = 1 while true do local sym_already_seen = false for _, note in ipairs(data.internal_notes) do if rfind(note, "^" .. nextsym .. " ") then sym_already_seen = true break end end if sym_already_seen then nextsym = nextsym + 1 else break end end return nextsym end -- FIXME: Move to utils -- Iterate over a chain of parameters, FIRST then PREF2, PREF3, ..., -- inserting into LIST (newly created if omitted). Return LIST. local function get_arg_chain(args, first, pref, list) if not list then list = {} end local val = args[first] local i = 2 while val do table.insert(list, val) val = args[pref .. i] i = i + 1 end return list end -- FIXME: Move to utils -- Set a chain of parameters, FIRST then PREF2, PREF3, ..., from LIST. local function set_arg_chain(args, first, pref, list) local param = first local i = 2 for _, val in ipairs(list) do args[param] = val param = pref .. i i = i + 1 end end -- For a given form in a conjugation table, we allow either strings or -- two-element lists {RUSSIAN, TRANSLIT}, where TRANSLIT can be nil -- (equivalent to a one-element list). When comparing them, we have to take -- this into account. local function forms_equal(form1, form2) if type(form1) ~= "table" then form1 = {form1} end if type(form2) ~= "table" then form2 = {form2} end return ut.equals(form1, form2) end local function contains_form(forms, form) for _, f in ipairs(forms) do if forms_equal(f, form) then return true end end return false end -- FIXME: Move to utils -- Append to the end of a chain of parameters, FIRST then PREF2, PREF3, ..., -- if the value isn't already present. local function append_to_arg_chain(args, first, pref, newval) local nextarg = first local i = 2 if newval == "" then error("Internal error: attempt to insert blank value into arg chain") end while true do if not args[nextarg] then break end if forms_equal(args[nextarg], newval) then return nil end nextarg = pref .. i i = i + 1 end args[nextarg] = newval return nextarg end local function get_true_arg(arg, not_off_by_1) -- We normally move all params down by one because the first param is the -- verb type; so reflect this correctly if the arg is numeric and -- not_off_by_1 isn't given return (not_off_by_1 or type(arg) ~= "number") and arg or arg + 1 end local function getarg(args, arg, default, paramdesc, not_off_by_1) paramdesc = paramdesc or "Parameter " .. get_true_arg(arg, not_off_by_1) default = default or "-" --PAGENAME = mw.loadData("Module:headword/data").pagename local NAMESPACE = mw.title.getCurrentTitle().nsText return args[arg] or (NAMESPACE == "Template" and default) or error(paramdesc .. " has not been provided") end local function check_stressed_arg(val, arg) -- don't consider suffixes if not rfind(val, "^%-") and not com.is_nonsyllabic(val) and not com.is_stressed(val) then error("Argument value " .. val .. " (parameter " .. get_true_arg(arg) .. ") must be stressed") end return val end local function get_stressed_arg(args, arg, default, paramdesc) local retval = getarg(args, arg, default, paramdesc) check_stressed_arg(retval, arg) return retval end local function get_opt_stressed_arg(args, arg) return args[arg] and get_stressed_arg(args, arg) or nil end local function check_unstressed_arg(val, arg) if com.is_stressed(val) then error("Argument value " .. val .. " (parameter " .. get_true_arg(arg) .. ") should not be stressed") end return val end local function get_unstressed_arg(args, arg, default, paramdesc) local retval = getarg(args, arg, default, paramdesc) check_unstressed_arg(retval, arg) return retval end local function get_opt_unstressed_arg(args, arg) return args[arg] and get_unstressed_arg(args, arg) or nil end local function no_stray_args(args, maxarg) for i=(maxarg + 1), 20 do if args[i] then error("Value for argument " .. get_true_arg(i) .. " not allowed (" .. args[i] .. " supplied)") end end end -- Extract a form spec (either a single string or a two-element table {RU, TR} -- into the component Russian and transliterated components. Normally, if -- an explicit manual translit wasn't given, the resulting translit will be -- nil; but if ALWAYS_TRANSLIT is given, it will be auto-transliterated from -- the Russian as needed. local function extract_russian_tr(form, always_translit) local ru, tr if type(form) == "table" then ru, tr = form[1], form[2] else ru = form end if not tr and always_translit then tr = ru and com.translit(ru) end return ru, tr end local function strip_arg_status_prefix(arg) if not arg then return arg, "" end local subbed arg, subbed = rsubb(arg, "^awkward%-", "") if subbed then return arg, "awkward-" end arg, subbed = rsubb(arg, "^none%-", "") if subbed then return arg, "none-" end return arg, "" end local function track(page) m_debug.track("ru-verb/" .. page) return true end -- Forward functions local present_e_a local present_e_b local present_e_c local present_je local present_i local make_reflexive local make_pre_reform local parse_and_stress_override local handle_forms_and_overrides local finish_generating_forms local make_table local all_verb_types = { "pf", "pf-intr", "pf-refl", "pf-impers", "pf-intr-impers", "pf-refl-impers", "impf", "impf-intr", "impf-refl", "impf-impers", "impf-intr-impers", "impf-refl-impers"} -- Examples of alternatives in use: -- past_m2: со́здал/созда́л, пе́редал/переда́л, о́тдал/отда́л, при́нялся/принялся́ -- past_m3: for verbs with three past masculine sg forms: за́нялся, заня́лся, занялс́я (заня́ться) -- past_n2: да́ло, дал́о; вз́яло, взяло́ -- past_pl2: разобрали́сь (разобрали́) -- past_m_short: short forms in 3a (исчез, сох, etc.) -- past_f_short: short forms in 3a (исчезла, сохла, etc.) -- past_n_short: short forms in 3a (исчезло, сохло, etc.) -- past_pl_short: short forms in 3a (исчезли, сохли, etc.) -- past_adv_parts: -- тереть: тере́вши, тёрши, short: тере́в -- умереть: умере́вши, у́мерши, short: умере́в -- pres_adv_part: сыпля, сыпя, лёжа (лежать) -- pres_2sg2: сыплешь, сыпешь -- pres_3sg2: сыплет, сыпет -- pres_1pl2: сыплем, сыпем -- pres_2pl2: сыплете, сыпете -- pres_3pl2: сыплют, сыпют -- futr_2sg2: насыплешь, насыпешь -- futr_3sg2: насыплет, насыпет -- futr_1pl2: насыплем, насыпем -- futr_2pl2: насыплете, насыпете -- futr_3pl2: насыплют, насыпют -- List of all main verb forms. Short forms (those ending in "_short") -- must be listed after the corresponding non-short forms. local all_main_verb_forms = { -- present tense "pres_1sg", "pres_2sg", "pres_3sg", "pres_1pl", "pres_2pl", "pres_3pl", -- future tense "futr_1sg", "futr_2sg", "futr_3sg", "futr_1pl", "futr_2pl", "futr_3pl", -- present-future tense. The conjugation functions generate the -- "present-future" tense instead of either the present or future tense, -- since the same forms are used in the present imperfect and future -- perfect. These forms are later copied into the present or future in -- finish_generating_forms(). "pres_futr_1sg", "pres_futr_2sg", "pres_futr_3sg", "pres_futr_1pl", "pres_futr_2pl", "pres_futr_3pl", -- imperative "impr_sg", "impr_pl", -- past "past_m", "past_f", "past_n", "past_pl", "past_m_short", "past_f_short", "past_n_short", "past_pl_short", -- active participles "pres_actv_part", "past_actv_part", -- passive participles "pres_pasv_part", "past_pasv_part", -- adverbial participles "pres_adv_part", "past_adv_part", "past_adv_part_short", -- infinitive "infinitive" } -- List of all verb forms. Each element is a list, where the first element -- is the "main" form and the remainder are alternatives. The following -- *MUST* hold: -- 1. Forms must be given in the order they will appear in the outputted -- table. -- 2. Short forms (those ending in "_short") must be listed after the -- corresponding non-short forms. -- 3. For each person, e.g. '2sg', there must be the same number of -- futr_PERSON, pres_PERSON and pres_futr_PERSON forms, and the alternative -- forms must be listed in the same order. -- -- FIXME!!! We should fix things so we no longer need to compute this table. local all_verb_forms = {} -- Compile all_verb_forms for _, mainform in ipairs(all_main_verb_forms) do local entry = {} table.insert(entry, mainform) for i=2,9 do table.insert(entry, mainform .. i) end table.insert(all_verb_forms, entry) end local prop_aliases = { pap="past_actv_part", paptail="past_actv_part_tail", paptailall="past_actv_part_tailall", ppp="past_pasv_part", ppptail="past_pasv_part_tail", ppptailall="past_pasv_part_tailall", prap="pres_actv_part", praptail="pres_actv_part_tail", praptailall="pres_actv_part_tailall", prpp="pres_pasv_part", prpptail="pres_pasv_part_tail", prpptailall="pres_pasv_part_tailall", padp="past_adv_part", padptail="past_adv_part_tail", padptailall="past_adv_part_tailall", padp_short="past_adv_part_short", padp_shorttail="past_adv_part_short_tail", padp_shorttailall="past_adv_part_short_tailall", pradp="pres_adv_part", pradptail="pres_adv_part_tail", pradptailall="pres_adv_part_tailall", } -- Table mapping "main" to the list of all forms in the series (e.g. -- past_m, past_m2, past_m3, etc.). If a main form (e.g. past_m) is missing, -- it needs to end up with a value of "", whereas the alternatives -- (e.g. past_m2, past_m3) need to end up with a value of nil. local main_to_all_verb_forms = {} -- List of the main verb forms for the past. local past_verb_forms = {"past_m", "past_f", "past_n", "past_pl"} -- List of the main verb forms for the present. local pres_verb_forms = {"pres_1sg", "pres_2sg", "pres_3sg", "pres_1pl", "pres_2pl", "pres_3pl"} -- List of the main verb forms for the future. local futr_verb_forms = {"futr_1sg", "futr_2sg", "futr_3sg", "futr_1pl", "futr_2pl", "futr_3pl"} -- List of the main verb forms for the imperative. local impr_verb_forms = {"impr_sg", "impr_pl"} -- List of the main verb forms for participles. local part_verb_forms = {"pres_actv_part", "past_actv_part", "pres_pasv_part", "past_pasv_part", "pres_adv_part", "past_adv_part", "past_adv_part_short"} -- List of the main verb forms for present participles. local pres_part_verb_forms = {"pres_actv_part", "pres_pasv_part", "pres_adv_part"} -- List of the main verb forms for past participles. local past_part_verb_forms = {"past_actv_part", "past_pasv_part", "past_adv_part", "past_adv_part_short"} -- Compile main_to_all_verb_forms. for _, proplist in ipairs(all_verb_forms) do main_to_all_verb_forms[proplist[1]] = proplist end -- Map listing the forms to be displayed, and the verb forms used to generate -- the displayed form, in order. For example, under past_m will be found -- {"past_m_short", "past_m", "past_m2", "past_m3"} because those forms in -- that order are displayed in the table under "masculine singular past". local disp_verb_form_map = {} for _, proplist in ipairs(all_verb_forms) do local key = proplist[1] -- if we find short forms, insert them at the beginning of the list for -- the corresponding full forms. This requires that short forms are -- listed in all_verb_forms after the corresponding full forms. if rfind(key, "_short$") then local full_key = rsub(key, "_short$", "") -- short forms should occur in list after full forms assert(#(disp_verb_form_map[full_key]) > 0) -- build entry for full form, consisting first of the short forms, -- in order, then the full forms, in order. local new_entry = {} for _, form in ipairs(proplist) do table.insert(new_entry, form) end for _, form in ipairs(disp_verb_form_map[full_key]) do table.insert(new_entry, form) end disp_verb_form_map[full_key] = new_entry elseif rfind(key, "^pres_futr") then -- skip these forms, not displayed else disp_verb_form_map[key] = mw.clone(proplist) end end local all_verb_props = mw.clone(all_verb_forms) local non_form_props = {"title", "perf", "intr", "impers", "categories", "notes", "internal_notes"} for _, prop in ipairs(non_form_props) do table.insert(all_verb_props, {prop}) end -- Clone parent's args while also assigning nil to empty strings and splitting -- arg sets (numeric args separated by "or"), assigning named args to -- all all sets. Handle aliases in the process. Extract conjugation type -- from the first arg of the arg set (for the initial arg set, this will be -- arg 2 because arg 1 is the verb type), assigning to '.conj_type' of the -- arg set. Return arg sets. local function split_args_handle_aliases(frame) local args = frame:getParent().args local arg_sets = {} local arg_set = {} -- Verb type, e.g. impf, pf, impf-intr, pf-intr, impf-refl, pf-refl, etc. -- Default to impf on the template page so that there is no script error. local verb_type = getarg(args, 1, "impf", "Verb type (first parameter)") local offset = 1 -- Find maximum-numbered arg, allowing for holes. local max_arg = 1 -- needs to be 1 not 0 so template pages display ok for pname, param in pairs(args) do if type(pname) == "number" and pname > max_arg then max_arg = pname end end -- Now gather the numbered arguments. for i=2,(max_arg + 1) do local end_arg_set = false if i == max_arg + 1 or args[i] == "or" then end_arg_set = true end if end_arg_set then table.insert(arg_sets, arg_set) arg_set = {} offset = i else arg_set[i - offset] = ine(args[i]) end end -- Insert named arguments into all arg sets, mapping aliases appropriately. for pname, param in pairs(args) do if type(pname) == "string" then local argval = ine(param) local mainprop, num = rmatch(pname, "^([a-z_]+)([0-9]*)$") for i=1,#arg_sets do if not mainprop then arg_sets[i][pname] = argval else mainprop = prop_aliases[mainprop] or mainprop arg_sets[i][mainprop .. num] = argval end end end end -- If we're conjugating a suffix, insert a pseudoconsonant at the beginning -- of all forms, so they get conjugated as if ending in a consonant. -- We remove the pseudoconsonant later. for i=1,#arg_sets do asif_prefix = (arg_sets[i]["asif_prefix"] or arg_sets[i][2] and rfind(arg_sets[i][2], "^%-") and PSEUDOCONS) if asif_prefix then for k, v in pairs(arg_sets[i]) do arg_sets[i][k] = rsub(v, "^%-", "-" .. asif_prefix) end end end -- Frob conjugation type. for i=1,#arg_sets do local arg1 = arg_sets[i][1] local conj_type if arg1 then local orig_arg1 = arg1 -- This complex spec matches matches 3°a, 3oa, 4a1a, 6c1a, -- 1a6a, 6a1as13, 6a1as14, 11*b, etc. conj_type = rmatch(arg1, "^([0-9]+[*°o0-9abc]*[abc]s?1?[34]?)") arg1 = rsub(arg1, "^[0-9]+[*°o0-9abc]*[abc]s?1?[34]?", "") if not conj_type then if rfind(arg1, "^irreg") then conj_type = "irreg" arg1 = rsub(arg1, "^irreg", "") end if not conj_type then -- Check for Cyrillic, a common mistake (esp. Cyrillic а) if rfind(orig_arg1, "[абцдеѣфгчийклмнопярстувшхызёюжэщьъ]") then error("Unrecognized conjugation type (WARNING, has Cyrillic in it): " .. orig_arg1) else error("Unrecognized conjugation type: " .. orig_arg1) end end end -- The * variant is conventionally written e.g. 11*b; if found in -- the conj_type, move it to the beginning of the remainder if rfind(conj_type, "%*") then conj_type = rsub(conj_type, "%*", "") arg1 = "*" .. arg1 end arg_sets[i][1] = arg1 else local NAMESPACE = mw.title.getCurrentTitle().nsText if NAMESPACE == "Template" and i == 1 then conj_type = "1a" else error("Must specify argument 2 (conjugation type)") end end arg_sets[i]["conj_type"] = conj_type end return arg_sets, verb_type end function export.do_generate_forms(arg_sets, verb_type, old) local set1 = arg_sets[1] local notes = get_arg_chain(set1, "notes", "notes") local forms = {} local categories = {} if not ut.contains(all_verb_types, verb_type) then error("Invalid verb type " .. verb_type) end local data = {} data.verb_type = verb_type --impersonal data.impers = rfind(verb_type, "impers") data.intr = rfind(verb_type, "intr") data.perf = rfind(verb_type, "^pf") data.iter = set1["iter"] data.nopres = set1["nopres"] data.nopast = set1["nopast"] data.nofutr = set1["nofutr"] data.noimpr = set1["noimpr"] if data.iter and data.perf then error("Iterative verbs must be imperfective") end data.old = old data.has_ppp = set1["has_ppp"] data.has_prpp = set1["has_prpp"] data.ppp_override = false data.prpp_override = false for _, form in ipairs(main_to_all_verb_forms["past_pasv_part"]) do if set1[form] then data.ppp_override = true break end end data.main_ppp_override = not not set1["past_pasv_part"] for _, form in ipairs(main_to_all_verb_forms["pres_pasv_part"]) do if set1[form] then data.prpp_override = true break end end data.internal_notes = {} local titles = {} for i=1,#arg_sets do local args = arg_sets[i] local conj_type = args.conj_type -- Support e.g. 3oa in place of 3°a conj_type = rsub(conj_type, "o", "°") track("conj-" .. conj_type) -- FIXME, convert to regular category track("conj-" .. conj_type .. "/" .. verb_type) -- FIXME, convert to regular category data.conj_type = conj_type data.cat_conj_types = {conj_type} if conj_type == "irreg" then data.title = "irregular" else data.title = conj_type end if not conjugations[conj_type] then error("Unknown conjugation type '" .. conj_type .. "'") end if args[2] then local inf, tr = nom.split_russian_tr(args[2]) if rfind(inf, "[тч]ься$") then inf = rsub(inf, "ся$", "") tr = nom.strip_tr_ending(tr, "ся") data.refl = true elseif rfind(inf, "ти́?сь$") then -- 7a (вы́вестись), 7b (вести́сь) or derivative of -йти́ (разойти́сь) inf = rsub(inf, "сь$", "") tr = nom.strip_tr_ending(tr, "сь") data.refl = true elseif rfind(inf, "[тч]ь$") then -- Allow monosyllabic infinitives to be specified without stress if com.is_monosyllabic(inf) and not rfind(inf, "^%-") then inf, tr = com.make_ending_stressed(inf, tr) end end if tr then args[2] = inf .. "//" .. tr else args[2] = inf end end if data.refl and data.intr then error("Can't specify -intr with reflexive verbs") end if data.has_ppp or data.has_prpp then if data.refl then error("Can't specify has_ppp=y or has_prpp=y with reflexive verbs") end if not data.intr then error("Can only specify has_ppp=y or has_prpp=y with intransitive verbs") end end data.shouldnt_have_ppp = data.refl or not data.has_ppp and data.intr data.shouldnt_have_prpp = data.refl or not data.has_prpp and data.intr if data.ppp_override and data.shouldnt_have_ppp then error("Shouldn't specify past passive participle with reflexive or intransitive verbs, if it's needed use has_ppp=y") elseif data.perf and not data.shouldnt_have_ppp and not data.ppp_override then -- possible omissions track("perfective-no-ppp") end if data.prpp_override and data.shouldnt_have_prpp then error("Shouldn't specify present passive participle with reflexive or intransitive verbs, if it's needed use has_prpp=y") end -- Call conjugation function. It will return a table of forms -- as if it's the first arg set. If it is in fact the first -- arg set, we just use the table directly (we may destructively -- modify it if there are later arg sets, but this is OK because -- no one else but us uses the table). Otherwise we need to -- append the values from the table to those of the previous -- arg sets. local arg_set_forms = conjugations[conj_type](args, data) if i == 1 then forms = arg_set_forms else for _, all_forms in pairs(main_to_all_verb_forms) do for _, form in ipairs(all_forms) do if arg_set_forms[form] then append_to_arg_chain(forms, all_forms[1], all_forms[1], arg_set_forms[form]) end end end end ut.insert_if_not(titles, data.title) if conj_type == "irreg" then table.insert(categories, "Russian irregular verbs") end -- For irregular verbs, if the verb didn't set a specific cat_conj_type, -- it will be the same as the conj_type and be "irreg". In that case, -- replace it with the title, which might be a proper conjugation type -- like 4a or 8c/b (and remove anything starting with a slash, to -- account for cases like 8c/b). After doing this, the cat_conj_type -- might still begin with "irreg" (for sufficiently irregular verbs that -- they can't be assigned to any of the normal classes), in which case -- we don't create a class for the verb beyond "Russian irregular verbs" -- (set above). if data.cat_conj_types[1] == "irreg" then data.cat_conj_types = {rsub(rsub(data.title, "/.*", ""), "⑨", "")} end for _, cat_conj_type in ipairs(data.cat_conj_types) do if not rmatch(cat_conj_type, "^irreg") then local class_num = rmatch(cat_conj_type, "^([0-9]+)") assert(class_num and class_num ~= "") table.insert(categories, "Russian class " .. class_num .. " verbs") table.insert(categories, "Russian class " .. cat_conj_type .. " verbs") end end end data.title = "class " .. table.concat(titles, " // ") .. (data.perf and " perfective" or " imperfective") .. (data.refl and " reflexive" or data.intr and " intransitive" or " transitive") .. (data.impers and " impersonal" or "") .. (data.iter and " iterative" or "") -- Perfective/imperfective if data.perf then table.insert(categories, "Russian perfective verbs") else table.insert(categories, "Russian imperfective verbs") end handle_forms_and_overrides(set1, forms, data) local function remove_pseudo(str) toremove = set1["asif_prefix"] or PSEUDOCONS if str == nil then return str end str = rsub(str, "^%-" .. toremove, "-") -- also handle prefix after space, e.g. in futures str = rsub(str, " %-" .. toremove, " -") return str end -- Remove pseudoconsonant we may have inserted; if no ending, insert -- "(no suffix)". for k, v in pairs(forms) do if forms[k] == "-" .. PSEUDOCONS or type(forms[k] == "table") and forms[k][1] == "-" .. PSEUDOCONS then -- Make the translit empty. forms[k] = {"(no suffix)", ""} else if type(forms[k]) == "table" then forms[k][1] = remove_pseudo(forms[k][1]) forms[k][2] = remove_pseudo(forms[k][2]) else forms[k] = remove_pseudo(forms[k]) end end end -- Catch errors in verb arguments that lead to the infinitive not matching -- page title, but only in the main namespace. local NAMESPACE = mw.title.getCurrentTitle().nsText if NAMESPACE == "" then local PAGENAME = mw.loadData("Module:headword/data").pagename for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local inf, inf_tr = extract_russian_tr(forms[form]) if inf then inf, _ = m_table_tools.separate_notes(inf) -- remove any footnote symbols (e.g. грясти́) local inf_noaccent = com.remove_accents(inf) if inf ~= "-" then if data.refl then if rfind(inf_noaccent, "и$") then inf_noaccent = inf_noaccent .. "сь" inf = inf .. "сь" else inf_noaccent = inf_noaccent .. "ся" inf = inf .. "ся" end end if inf_noaccent ~= PAGENAME then error("Infinitive " .. inf .. " doesn't match pagename " .. PAGENAME) end end end end end -- Reflexive/intransitive/transitive if set1["reflex_stress"] then track("reflex-stress") end if data.refl then local reflex_stress = set1["reflex_stress"] or data.default_reflex_stress -- "ся́" make_reflexive(forms, reflex_stress and reflex_stress ~= "n" and reflex_stress ~= "no") table.insert(categories, "Russian reflexive verbs") elseif data.intr then table.insert(categories, "Russian intransitive verbs") else table.insert(categories, "Russian transitive verbs") end -- Impersonal if data.impers then table.insert(categories, "Russian impersonal verbs") end -- Iterative if data.iter then table.insert(categories, "Russian iterative verbs") end if data.old then make_pre_reform(forms) end finish_generating_forms(forms, data) return forms, data.title, data.perf, data.intr or data.refl, data.impers, categories, notes, data.internal_notes end local function fetch_forms(forms) local function fetch_one_form(form) local val = forms[form] local ru, tr if type(val) == "table" then ru, tr = val[1], val[2] elseif type(val) == "string" and val ~= "" and val ~= "-" then ru = val end if not ru then return nil end local ruentry, runotes = m_table_tools.get_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.get_notes(tr) end -- There shouldn't be any links. -- ruentry = m_links.remove_links(ruentry) -- There shouldn't be any vertical bars. -- ruentry = rsub(ruentry, "|", "<!>") -- if trentry then -- trentry = rsub(trentry, "|", "<!>") -- end return trentry and ruentry .. "//" .. trentry or ruentry end local vals = {} for _, proplist in ipairs(all_verb_forms) do local vallist = {} local propname = proplist[1] if not rfind(propname, "^pres_futr") then for _, prop in ipairs(proplist) do local val = fetch_one_form(prop) if val then table.insert(vallist, val) end end if #vallist > 0 then table.insert(vals, propname .. "=" .. table.concat(vallist, ",")) end end end return table.concat(vals, "|") end function export.generate_forms(frame) local arg_sets, verb_type = split_args_handle_aliases(frame) local old = frame.args["old"] or arg_sets[1]["old"] local forms, title, perf, intr, impers, categories, notes, internal_notes = export.do_generate_forms(arg_sets, verb_type, old) return fetch_forms(forms) end local function concat_vals(val) if type(val) == "table" then return table.concat(val, ",") else return val end end -- The main entry point. -- This is the only function that can be invoked from a template. function export.show(frame) local arg_sets, verb_type = split_args_handle_aliases(frame) local old = frame.args["old"] or arg_sets[1]["old"] local arg_sets_clone if test_new_ru_verb_module then -- arg_sets may be modified by do_generate_forms() arg_sets_clone = mw.clone(arg_sets) end local forms, title, perf, intr, impers, categories, notes, internal_notes = export.do_generate_forms(arg_sets, verb_type, old) -- Test code to compare existing module to new one. if test_new_ru_verb_module then local m_new_ru_verb = require("Module:User:Benwing2/ru-verb") local newforms, newtitle, newperf, newintr, newimpers, newcategories, newnotes, newinternal_notes = m_new_ru_verb.do_generate_forms(arg_sets_clone, verb_type, old) local vals = mw.clone(forms) vals.title = title vals.perf = perf vals.intr = intr vals.impers = impers vals.categories = categories vals.notes = notes vals.internal_notes = internal_notes local newvals = mw.clone(newforms) newvals.title = newtitle newvals.perf = newperf newvals.intr = newintr newvals.impers = newimpers newvals.categories = newcategories newvals.notes = newnotes newvals.internal_notes = newinternal_notes local difconj = false for _, proplist in ipairs(all_verb_props) do for _, prop in ipairs(proplist) do local val = vals[prop] local newval = newvals[prop] -- deal with impedance mismatch between old style (plain string) -- and new style (Russian/translit array), and empty string vs. nil if not ut.contains(non_form_props, prop) then if type(val) == "string" then val = {val} end if val and val[1] == "" then val = nil end if type(newval) == "string" then newval = {newval} end if newval and newval[1] == "" then newval = nil end end -- Ignore changes in pres_futr_*, which aren't displayed if not forms_equal(val, newval) and not rfind(prop, "^pres_futr") then -- Uncomment this to display the particular case and -- differing forms. --error(prop .. " " .. (val and concat_vals(val) or "nil") .. " || " .. (newval and concat_vals(newval) or "nil")) difconj = true break end end end track(difconj and "different-conj" or "same-conj") end return make_table(forms, title, perf, intr, impers, notes, internal_notes, old) .. m_utilities.format_categories(categories, lang) end -- Implementation of template 'ru-verb cat'. function export.catboiler(frame) local SUBPAGENAME = mw.loadData("Module:headword/data").pagename local cats = {} local cls, variant, pattern = rmatch(SUBPAGENAME, "^Russian class ([0-9]*)(°?)([abc]?) verbs") local text = nil if not cls then error("Invalid category name, should be e.g. \"Russian class 3a verbs\"") end if pattern == "" then table.insert(cats, "Russian verbs by class|" .. cls .. variant) text = "This category contains Russian class " .. cls .. " verbs." else table.insert(cats, "Russian verbs by class and accent pattern|" .. cls .. pattern) table.insert(cats, "Russian class " .. cls .. " verbs|" .. pattern) text = "This category contains Russian class " .. cls .. " verbs of " .. "accent pattern " .. pattern .. ( variant == "" and "" or " and variant " .. variant) .. ". " .. ( pattern == "a" and "With this pattern, all forms are stem-stressed." or pattern == "b" and "With this pattern, all forms are ending-stressed." or "With this pattern, the first singular present indicative and all forms " .. "outside of the present indicative are ending-stressed, while the remaining " .. "forms of the present indicative are stem-stressed.").. ( variant == "" and "" or cls == "3" and " The variant code indicates that the -н of the stem " .. "is missing in most non-present-tense forms." or " The variant code indicates that the present tense is not " .. "[[Appendix:Glossary#iotation|iotated]]. (In most verbs of this class, " .. "the present tense is iotated, e.g. иска́ть with present tense " .. "ищу́, и́щешь, и́щет, etc.)") end return text .. "\n" .. mw.getCurrentFrame():expandTemplate{title="ru-categoryTOC", args={}} .. m_utilities.format_categories(cats, lang, nil, nil, "force") end -- Implementation of poscatboiler handler for Russian verb cats. Loaded from -- [[Module:category tree/poscatboiler/data/lang-specific]]. function export.poscatboiler_verb_class_handler(cls, variant, pattern) if pattern == "" then return { description = "Russian class " .. cls .. " verbs.", breadcrumb = cls, parents = {{name = "verbs by class", sort = cls .. variant}}, } else return { description = "Russian class " .. cls .. " verbs of " .. "accent pattern " .. pattern .. ( variant == "" and "" or " and variant " .. variant) .. ". " .. ( pattern == "a" and "With this pattern, all forms are stem-stressed." or pattern == "b" and "With this pattern, all forms are ending-stressed." or "With this pattern, the first singular present indicative and all forms " .. "outside of the present indicative are ending-stressed, while the remaining " .. "forms of the present indicative are stem-stressed.") .. ( variant == "" and "" or cls == "3" and " The variant code indicates that the -н of the stem " .. "is missing in most non-present-tense forms." or " The variant code indicates that the present tense is not " .. "[[Appendix:Glossary#iotation|iotated]]. (In most verbs of this class, " .. "the present tense is iotated, e.g. иска́ть with present tense " .. "ищу́, и́щешь, и́щет, etc.)"), breadcrumb = cls .. variant .. pattern, parents = { {name = "class " .. cls .. " verbs", sort = pattern}, {name = "verbs by class and accent pattern", sort = cls .. pattern}, }, } end end --[=[ Functions for working with stems, paradigms, Russian/translit ]=] -- Combine a stem with optional translit with an ending and possibly a foonote -- symbol (which may be a tuple {RUNOTES, TRNOTES}), returning a tuple -- {RUSSIAN, TR}. local function combine(stem, tr, ending, note) if not ending or ending == "-" then return nil end local arg_status ending, arg_status = strip_arg_status_prefix(ending) if stem ~= "" and com.is_stressed(ending) then stem, tr = com.make_unstressed_once(stem, tr) end stem = arg_status .. stem if not note then return nom.concat_russian_tr(stem, tr, ending, nil, "dopair") else local runotes, trnotes = extract_russian_tr(note) local ruending, trending = nom.concat_russian_tr(ending, nil, runotes, trnotes) return nom.concat_russian_tr(stem, tr, ruending, trending, "dopair") end end -- Set an individual form PARAM in FORMS with value based on stem STEM (with -- optional translit TR), ENDINGS (either a single string or a list of strings) -- and NOTE (nil, a string, or a tuple {RUSSIAN, TR}). If there are multiple -- endings listed, they will go successively into PARAM, PARAM2, etc. -- (e.g. past_m, past_m2, etc.). local function set_form(forms, param, stem, tr, endings, note) if type(endings) ~= "table" then endings = {endings} end local entries = {} for _, val in ipairs(endings) do ut.insert_if_not(entries, combine(stem, tr, val, note)) end set_arg_chain(forms, param, param, entries) end -- Append to an individual form PARAM in FORMS with value based on stem STEM -- (with optional translit TR), ENDINGS (either a single string or a list of -- strings) and NOTE (nil, a string, or a tuple {RUSSIAN, TR}). If there are -- multiple endings listed, they will go successively into PARAM, PARAM2, etc. -- (e.g. past_m, past_m2, etc.), provided there are no existing forms already -- present. Duplicate forms aren't inserted. local function append_form(forms, param, stem, tr, endings, note) if type(endings) ~= "table" then endings = {endings} end for _, val in ipairs(endings) do append_to_arg_chain(forms, param, param, combine(stem, tr, val, note)) end end local function append_pres_futr(forms, stem, tr, sg1, sg2, sg3, pl1, pl2, pl3, note) append_form(forms, "pres_futr_1sg", stem, tr, sg1, note) append_form(forms, "pres_futr_2sg", stem, tr, sg2, note) append_form(forms, "pres_futr_3sg", stem, tr, sg3, note) append_form(forms, "pres_futr_1pl", stem, tr, pl1, note) append_form(forms, "pres_futr_2pl", stem, tr, pl2, note) append_form(forms, "pres_futr_3pl", stem, tr, pl3, note) end local function append_participles_2stem(forms, pres_stem, pres_tr, past_stem, past_tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, pres_note, past_note) append_form(forms, "pres_actv_part", pres_stem, pres_tr, pres_actv, pres_note) append_form(forms, "pres_pasv_part", pres_stem, pres_tr, pres_pasv, pres_note) append_form(forms, "pres_adv_part", pres_stem, pres_tr, pres_adv, pres_note) append_form(forms, "past_actv_part", past_stem, past_tr, past_actv, past_note) append_form(forms, "past_adv_part", past_stem, past_tr, past_adv, past_note) append_form(forms, "past_adv_part_short", past_stem, past_tr, past_adv_short, past_note) end local function append_participles(forms, stem, tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, note) append_participles_2stem(forms, stem, tr, stem, tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, note, note) end local function set_ppp(forms, stem, tr, ending, note) set_form(forms, "past_pasv_part", stem, tr, ending, note) end local function append_ppp(forms, stem, tr, ending, note) append_form(forms, "past_pasv_part", stem, tr, ending, note) end local function append_imper(forms, stem, tr, sg, pl, note) append_form(forms, "impr_sg", stem, tr, sg, note) append_form(forms, "impr_pl", stem, tr, pl, note) end local function set_past(forms, stem, tr, m, f, n, pl, note) set_form(forms, "past_m", stem, tr, m, note) set_form(forms, "past_f", stem, tr, f, note) set_form(forms, "past_n", stem, tr, n, note) set_form(forms, "past_pl", stem, tr, pl, note) end local function append_past(forms, stem, tr, m, f, n, pl, note) append_form(forms, "past_m", stem, tr, m, note) append_form(forms, "past_f", stem, tr, f, note) append_form(forms, "past_n", stem, tr, n, note) append_form(forms, "past_pl", stem, tr, pl, note) end -- Prepend a possibly-stressed prefix to all forms; if prefix is stressed, -- destress the forms before prepending. FIXME: Should support explicit -- manual translit. local function prepend_prefix(forms, prefix, pre_two_cons_prefix) pre_two_cons_prefix = pre_two_cons_prefix or prefix local stressed_prefix = com.is_stressed(prefix) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) if tr then error("Explicit manual translit not yet supported") end -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then if stressed_prefix then ru = com.make_unstressed(ru) end if rfind(ru, "^[" .. com.cons .. "][" .. com.cons .. "]") then forms[key] = pre_two_cons_prefix .. ru else forms[key] = prefix .. ru end end end end -- Apply regex substitution FROM -> TO to all forms. FIXME: Should support -- explicit manual translit. local function rsub_forms(forms, from, to) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) if tr then error("Explicit manual translit not yet supported") end -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then forms[key] = rsub(ru, from, to) end end end local variant_to_title = { ["[(2)]"] = "[②]", ["(2)"] = "②", ["[(3)]"] = "[③]", ["(3)"] = "③", ["[(4)]"] = "[④]", ["(4)"] = "④", ["[(5)]"] = "[⑤]", ["(5)"] = "⑤", ["[(6)]"] = "[⑥]", ["(6)"] = "⑥", ["[(7)]"] = "[⑦]", ["(7)"] = "⑦", ["[(8)]"] = "[⑧]", ["(8)"] = "⑧", ["(9)"] = "⑨", ["щ"] = "(-щ-)", ["ё"] = "(-ё-)", ["о"] = "(-о-)", ["жд"] = "(-жд-)", } local function prepare_past_stress_indicator(past_stress) if not past_stress or past_stress == "a" then return "" end past_stress = rsub(past_stress, "%(1%)", "①") past_stress = rsub(past_stress, "(.),%1①", "%1[①]") past_stress = rsub(past_stress, "(.)①,%1", "%1[①]") past_stress = rsub(past_stress, "''", "&#39;&#39;") past_stress = rsub(past_stress, "-nd", "") past_stress = rsub(past_stress, "-bd", "") return "/" .. past_stress end local function parse_variants(data, variants, allowed) -- Need to set these to nil in case of multiple arg sets data.imper_variant = nil data.var4 = nil data.var5 = nil data.var6 = nil data.ppp = nil data.var9 = nil data.shch = nil data.yo = nil data.o = nil data.zhd = nil data.star = nil variants = variants or "" local variant_title = "" if variants ~= "" then -- short-circuit the most common case -- Only recognize * variant for long-variant prefix at the beginning -- of the variant code block (where it gets moved if it's in the -- middle of the conjugation type, as it normally is) because a * -- also occurs in b*, a past stress variant code. if rfind(variants, "^%*") then -- Specify that the present/future tense has extra -о in the prefix: -- types 9*b (e.g. растере́ть, futr_1sg разотру́) and 11*b (e.g. изли́ть, -- futr_1sg изолью́). It can also occur with type 7*b (in -че́сть, -- e.g. счесть, сочту́; расче́сть, разочту́) and type 8*b (in -же́чь, e.g. -- сжечь, сожгу́) but these are always irregular and require the -- present tense to be specified explicitly. It can also occur -- with type 14*b (e.g. размя́ть, разомну́; сжать, сожну́; подожа́ть, подожму́), -- but for these verbs the present tense is unpredictable and -- must be specified explicitly. -- -- This can also occur where the extra -о occurs in the infinitive -- and past, but not the present tense: type 5*c (in -гна́ть, e.g. -- согна́ть, сгоню́; разогна́ться, разгоню́сь), type 6*c (in -стла́ть, e.g. -- подостла́ть, подстелю́; разостла́ть, расстелю́), type 6°*c -- (in -зва́ть, -бра́ть, -дра́ть, e.g. подозва́ть, подзову́; разобра́ться, разберу́сь); -- but these are always irregular and require the present tense -- to be specified explicitly. if not ut.contains(allowed, "*") then error("Variant " .. var .. " not allowed for this verb class") end data.star = true variants = rsub(variants, "^*", "") end -- Allow brackets around both 5 and 6, e.g. [(5)(6)] variants = rsub(variants, "%[(%([56]%))(%([56]%))%]", "[%1][%2]") -- Handle all remaining variants. We do this using an rsub() function, -- where we pull out, parse and remove each variant in turn. variants = rsub(variants, "(%[?%(?[23456789ёощийьж+][дp]?%)?%]?)", function(var) if ut.contains({"(2)", "[(2)]", "(3)", "[(3)]", "и", "й", "ь"}, var) then if data.imper_variant then error("Saw two imperative variants " .. data.imper_variant .. " and " .. var) end local is_23 = ut.contains({"(2)", "[(2)]", "(3)", "[(3)]"}, var) if is_23 and not ut.contains(allowed, "23") or not is_23 and not ut.contains(allowed, "и") then error("Variant " .. var .. " not allowed for this verb class") end data.imper_variant = var elseif ut.contains({"(4)", "[(4)]"}, var) then if data.var4 then error("Saw two variant-4 specs " .. data.var4 .. " and " .. var) end if not ut.contains(allowed, "4") then error("Variant " .. var .. " not allowed for this verb class") end data.var4 = var == "(4)" and "req" or "opt" elseif ut.contains({"(5)", "[(5)]"}, var) then if data.var5 then error("Saw two variant-5 specs " .. data.var5 .. " and " .. var) end if not ut.contains(allowed, "5") then error("Variant " .. var .. " not allowed for this verb class") end data.var5 = var == "(5)" and "req" or "opt" elseif ut.contains({"(6)", "[(6)]"}, var) then if data.var6 then error("Saw two variant-6 specs " .. data.var6 .. " and " .. var) end if not ut.contains(allowed, "6") then error("Variant " .. var .. " not allowed for this verb class") end data.var6 = var == "(6)" and "req" or "opt" elseif ut.contains({"(7)", "[(7)]", "(8)", "[(8)]", "+p"}, var) then if data.shouldnt_have_ppp then error("Shouldn't specify past passive participle with reflexive or intransitive verbs, if it's needed use has_ppp=y") end if data.ppp then error("Saw two past passive participle specs " .. data.ppp .. " and " .. var) end if ut.contains({"(7)", "[(7)]"}, var) and not ut.contains(allowed, "7") or ut.contains({"(8)", "[(8)]"}, var) and not ut.contains(allowed, "8") or var == "+p" and not ut.contains(allowed, "+p") then error("Variant " .. var .. " not allowed for this verb class") end data.ppp = var elseif var == "(9)" then if data.var9 then error("Saw (9) twice") end if not ut.contains(allowed, "9") then error("Variant " .. var .. " not allowed for this verb class") end data.var9 = true elseif var == "щ" then -- specify that the 1sg pres/futr and past passive participle -- of class 4/5/6 verbs iotate -т to -щ instead of -ч; cf. -- похи́тить (похи́щу) (4a), защити́ть (защищу́) (4b), -- поглоти́ть (поглощу́) (4c), клевета́ть (клевещу́) (6c) if data.shch then error("Saw щ twice") end if not ut.contains(allowed, "щ") then error("Variant " .. var .. " not allowed for this verb class") end data.shch = "щ" elseif var == "ё" then -- specify that the past passive participle has ё instead of е if data.yo then error("Saw ё twice") end if not ut.contains(allowed, "ё") then error("Variant " .. var .. " not allowed for this verb class") end data.yo = true elseif var == "о" then -- specify that the past passive participle has о instead of е -- NOTE: Not currently allowed as a user-specifiable variant if data.o then error("Saw о twice") end if not ut.contains(allowed, "о") then error("Variant " .. var .. " not allowed for this verb class") end data.o = true elseif var == "жд" then -- specify that the past passive participle of class 4/5/6 verbs -- iotates -д to -жд instead of -ж if data.zhd then error("Saw жд twice") end if not ut.contains(allowed, "жд") then error("Variant " .. var .. " not allowed for this verb class") end data.zhd = true else error("Unrecognized variant spec: " .. var) end variant_title = variant_title .. (variant_to_title[var] or "") return "" end) variant_title = rsub(variant_title, "%[⑤%]%[⑥%]", "[⑤⑥]") end if variants ~= "" and not ut.contains(allowed, "past") then error("Past stress " .. variants .. " not allowed for this verb class") end if data.yo and not data.ppp then error("Variant ё specified without calling for past passive participle") end if data.o and not data.ppp then error("Variant о specified without calling for past passive participle") end if data.zhd and not data.ppp then error("Variant жд specified without calling for past passive participle") end if data.perf and not data.ppp and not data.ppp_override and not data.shouldnt_have_ppp and not data.impers then error("For perfective transitive verbs, need to specify past passive participle by variant or override; use |ppp=- if no such participle") end data.past_stress = variants == "" and "a" or rsub(variants, "/", "") data.title = data.title .. prepare_past_stress_indicator(data.past_stress) .. variant_title if data.star then data.title = rsub(data.title, "^([0-9]+°?)", "%1*") end -- If there's an override of past_pasv_part, generate the normal participle -- so we can determine whether the override is irregular. But set a flag -- so we erase any automatically generated past passive participles that -- aren't overridden. This happens for example in обнять, where there are -- two automatically generated past passive participles but a single -- ppp=о́внятый override. if not data.ppp and data.main_ppp_override then data.ppp = "+p" data.ppp_auto_generated = true end end local function set_past_by_stress(forms, past_stresses, prefix, prefixtr, base, basetr, args, data, no_pastml, note) -- If there isn't manual translit for the prefix, we need to supply it -- if there's manual translit for the base, because we often concatenate -- prefix to the base. local prefixtr = prefixtr or basetr and com.translit(prefix) for _, past_stress in ipairs(rsplit(past_stresses, ",")) do local pastml = no_pastml and "" or "л" local stressed_prefixtr if prefix == "пере" then stressed_prefix = "пе́ре" stressed_prefixtr = "pe" .. AC .. "re" elseif prefix == "раз" then stressed_prefix = "ро́з" stressed_prefixtr = "ro" .. AC .. "z" elseif prefix == "рас" then -- Does this ever occur? stressed_prefix = "ро́с" stressed_prefixtr = "ro" .. AC .. "s" elseif prefix == "ра" and rfind(base, "^[сз]") then -- Type 9/11/14/16 with automatically split prefix; may never happen. stressed_prefix = "ро́" stressed_prefixtr = "ro" .. AC else stressed_prefix, stressed_prefixtr = com.make_ending_stressed(prefix, prefixtr) end -- Normally the base is stressed and the prefix isn't, but it could -- be the other way around, e.g. in запереть and запереться, where -- the stress on the prefix is used to get prefix-stressed participles. -- To deal with this, we usually combine base and prefix unchanged, -- but in combination with stressed_prefix we always want an unstressed -- base, and when a stressed -ся́ is called for, we want both of them -- unstressed. local ubase, ubasetr = com.make_unstressed(base, basetr) local uprefix, uprefixtr = com.make_unstressed(prefix, prefixtr) local prefixbase = prefix .. base local prefixbasetr = basetr and prefixtr .. basetr local stressed_prefix_ubase = stressed_prefix .. ubase local stressed_prefix_ubasetr = ubasetr and stressed_prefixtr .. ubasetr local uprefixubase = uprefix .. ubase local uprefixubasetr = ubasetr and uprefixtr .. ubasetr if past_stress == "a" then -- (/под/пере/при/по)забы́ть, раздобы́ть, (/пере/по)забы́ться append_past(forms, prefixbase, prefixbasetr, pastml, "ла", "ло", "ли", note) elseif past_stress == "a(1)" then -- вы́дать, вы́быть, etc.; also проби́ть with the meaning -- "to strike (of a clock)" (which is a(1),a or similar) append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, "ла", "ло", "ли", note) elseif past_stress == "b" then append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", "ло́", "ли́", note) elseif past_stress == "b*" then if not data.refl then error("Only reflexive verbs can take past stress variant " .. past_stress) end -- See comment in type c''. We want to see whether we actually -- added an argument, and if so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. (note or ""))) if argset and not args[argset] and not data.impers then data.default_reflex_stress = "ся́" end append_past(forms, prefixbase, prefixbasetr, {}, "ла́", "ло́", "ли́", note) elseif past_stress == "c" then -- изда́ть, возда́ть, сдать, пересозда́ть, воссозда́ть, надда́ть, наподда́ть, etc. -- быть, избы́ть, сбыть -- клясть, закля́сть append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", "ло", "ли", note) elseif past_stress == "c(1)" then -- прибы́ть, убы́ть -- прокля́сть -- also, c(1),c: -- зада́ть, обда́ть, отда́ть, подда́ть, переда́ть (пе́редал), преда́ть, прода́ть, разда́ть (ро́здал), созда́ть, etc. -- отбы́ть, побы́ть, пробы́ть -- also, c,c(1): -- добы́ть -- Because the prefix may vary depending on stress (esp. for -- раздать [ро́здал/раздала́]), we need to separate the endings that -- take the stressed prefix and those that take the unstressed -- prefix with stressed ending. append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) append_past(forms, prefixbase, prefixbasetr, {}, "ла́", {}, {}, note) elseif past_stress == "c'" then -- дать --same with "взять" append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", {"ло", "ло́"}, "ли", note) elseif past_stress == "c''" or past_stress == "c''-nd" or past_stress == "c''-bd" then if not data.refl then error("Only reflexive verbs can take past stress variant " .. past_stress) end -- c'' (-ся́ dated): all verbs in -да́ться; избы́ться, сбы́ться; all verbs in -кля́сться -- c''-nd (-ся́ not dated): various verbs in -ня́ться per Zaliznyak -- c''-bd (-ся́ becoming dated): various verbs in -ня́ться per ruwikt local note_symbol = past_stress == "c''-nd" and "" or next_note_symbol(data) append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", {"ло́", "ло"}, {"ли́", "ли"}) -- We want to see whether we actually added an argument, and if -- so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. note_symbol .. (note or ""))) -- Only display the internal note and set the default reflex -- stress if the form with the note will be displayed (i.e. not -- impersonal, and no override of this form). FIXME: We should -- have a more general mechanism to check for this. if not args[argset] and not data.impers then ut.insert_if_not(data.internal_notes, past_stress == "c''" and note_symbol .. " Dated." or past_stress == "c''-bd" and note_symbol .. " Becoming dated." or nil) data.default_reflex_stress = "ся́" end elseif past_stress == "c''(1)" then -- запере́ться -- See comment in type c''. We want to see whether we actually -- added an argument, and if so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. (note or ""))) if argset and not args[argset] and not data.impers then data.default_reflex_stress = "ся́" end append_past(forms, prefixbase, prefixbasetr, {}, "ла́", "ло́", "ли́", note) append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) else error("Unrecognized past-stress value " .. past_stress .. ", should be a, a(1), b, b*, c, c(1), c', c'', c''-nd, c''-bd, c''(1) or comma-separated list") end end end -- Split a verb stem into a possibly multisyllabic prefix (пере-, переиз-, -- воссоз-, повы́-, etc.) and a single-syllable main verb (-тер-, -ли́-, -гре́-, -- etc.). Normally the splitting is done simply by looking for alternating -- vowel/consonant sequences, meaning that e.g. разгре́ will be split as -- ра + згре́ and растер will be split as ра + стер. For most purposes, this -- doesn't matter, but for the * variant it does; in that case, if it is -- known that the main verb base always begins with a single consonant, -- specify SINGLE_CONS_BASE and then e.g. растер will be split as рас + тер. local function split_monosyllabic_main_verb(ru, tr, single_cons_base) local rusyl, trsyl = com.split_syllables(ru, tr) local last_ru = rusyl[#rusyl] local last_tr = trsyl and trsyl[#trsyl] table.remove(rusyl, #rusyl) local prefix_ru = table.concat(rusyl, "") local prefix_tr if trsyl then table.remove(trsyl, #trsyl) prefix_tr = table.concat(trsyl, "") end if single_cons_base then local cons_to_move, rest = rmatch(last_ru, "^([" .. com.cons .. "]+)([" .. com.cons .. "].*)$") if cons_to_move then prefix_ru = prefix_ru .. cons_to_move last_ru = rest end if last_tr then cons_to_move, rest = rmatch(last_tr, "^([" .. com.tr_cons .. "]+)([" .. com.tr_cons .. "].*)$") if cons_to_move then prefix_tr = prefix_tr .. cons_to_move last_tr = rest end end end return prefix_ru, prefix_tr, last_ru, last_tr end local function split_known_main_verb(arg, mains) -- Given an argument (which may be RUSSIAN//TR), split the prefix from -- the main verb, which should be one of the verbs in MAINS (which can be -- a -- single verb or a list of verbs, but in either case all verbs -- need to be stressed). This correctly handles stressed and unstressed -- prefixes. local stem, tr = nom.split_russian_tr(arg) if type(mains) ~= "table" then mains = {mains} end for _, main in ipairs(mains) do assert(com.is_stressed(main)) if rfind(stem, main .. "$") then stem, tr = nom.strip_ending(stem, tr, main) if com.is_stressed(stem) then error("Two stresses in " .. arg) end return stem, tr, main, nil end main = com.make_unstressed_once(main) if rfind(stem, main .. "$") then stem, tr = nom.strip_ending(stem, tr, main) if com.is_unstressed(stem) then error("No stresses in " .. arg) end return stem, tr, main, nil end end if #mains == 1 then error("Argument " .. arg .. " doesn't end in " .. mains[1]) else error("Argument " .. arg .. " doesn't end in any of " .. table.concat(mains, ",")) end end local function construct_long_prefix_variant(prefix) if rfind(prefix, "рас$") then return rsub(prefix, "рас$", "разо") end if rfind(prefix, "ис$") then return rsub(prefix, "ис$", "изо") end if rfind(prefix, "вс$") then return rsub(prefix, "вс$", "взо") end return prefix .. "о" end local function append_imper_by_variant(forms, stem, tr, variant, verbclass, note) local vowel_stem = is_vowel_stem(stem) local stress = rmatch(verbclass, "([abc])$") if not stress then error("Unrecognized verb class '" .. verbclass .. "', should end with a, b or c") end local longend = stress == "a" and "и" or "и́" local shortend = vowel_stem and (com.is_unstressed(stem) and "́й" -- accent on previous vowel or "й") or "ь" local function append_short_imper() append_imper(forms, stem, tr, shortend, shortend .. "те", note) end local function append_long_imper() append_imper(forms, stem, tr, longend, longend .. "те", note) end if variant and variant ~= "" then track("explicit-imper") track("explicit-imper/" .. verbclass) end if variant == "(2)" then -- use short variants with вы́- (for these verbs, long is expected) if not rfind(stem, "^вы́-") then error("Should only specify imperative variant (2) with verbs in вы́-, not " .. stem) end append_short_imper() elseif variant == "[(2)]" then -- use both long and short variants append_long_imper() append_short_imper() elseif variant == "(3)" then -- long in singular, short in plural append_imper(forms, stem, tr, longend, shortend .. "те", note) elseif variant == "[(3)]" then -- long and short in singular, short in plural append_imper(forms, stem, tr, {longend, shortend}, shortend .. "те", note) elseif variant == "ь" or variant == "й" then -- short variants wanted append_short_imper() elseif variant == "и" then -- long variants wanted append_long_imper() else assert(not variant or variant == "") if vowel_stem then if verbclass == "4b" or verbclass == "4c" or ( verbclass == "4a" and rfind(stem, "^вы́-")) then append_long_imper() else append_short_imper() end else -- consonant stem if stress == "b" or stress == "c" then append_long_imper() else assert(stress == "a") -- "и" after вы́-, e.g. вы́садить -- "и" after final щ, e.g. тара́щиться (although this particular -- verb has a [(3)] spec attached to it) if rfind(stem, "^вы́-") or rfind(stem, "щ$") or -- "и" after two consonants in a row (мо́рщить, зафре́ндить) rfind(stem, "[бвгджзклмнпрстфхцчшщь][бвгджзклмнпрстфхцчшщ]$") then append_long_imper() else -- "ь" after a single consonant (бре́дить) append_short_imper() end end end end end -- Compute the past passive participle stem for verbs that require it to be -- iotated (class 4, and class 5 in -еть). local function iotated_ppp(data, stem, tr) local iotated_stem, iotated_tr if data.zhd then local subbed iotated_stem, subbed = rsubb(stem, "з?д$", "жд") if not subbed then error("Variant -жд- specified but stem " .. stem .. " doesn't end in -д") end if tr then iotated_tr, subbed = rsubb(tr, "z?d$", "žd") if not subbed then error("Variant -жд- specified but translit " .. tr .. " doesn't end in -d") end end else iotated_stem, iotated_tr = com.iotation(stem, tr, data.shch) end return iotated_stem, iotated_tr end -- Set the past passive participle of verbs where the stress is moved left -- from the ending by one syllable (if possible) if the ending is stressed, -- otherwise left as-is (except class 1a in -е́ть, which has ending-stressed -- -ённый). This applies to classes 1, 2, 3, 5, 6, 10 and 13. The stem comes -- from the infinitive, iotated in class 5 -еть/-ѣть verbs. The participle -- ending is -анный/-янный for verbs in -ать/-ять, -енный/-ённый for verbs in -еть, -- -ѣнный/-ѣ̈нный for verbs in -ѣть, otherwise -тый. local function set_moving_ppp(forms, data) if not data.ppp then return end -- NOTE: No need to check for multiple infinitives because no verbs have -- them normally, and we probably don't want to check for overrides here -- (e.g. it would break достичь and related verbs, which have participles -- based on the infinitive достигнуть). local infinitive, infinitivetr = extract_russian_tr(forms["infinitive"]) local stem, ending = rmatch(infinitive, "^(.*)([аеѣоуя]́?ть)$") if not stem then error("Strange infinitive " .. infinitive .. " when trying to create participle") end local tr, endingtr if infinitivetr then if ending == "ять" or ending == "я́ть" then tr, endingtr = rmatch(infinitivetr, "^(.*)(ja" .. AC .. "?tʹ)$") else tr, endingtr = rmatch(infinitivetr, "^(.*)([aeěou]" .. AC .. "?tʹ)$") end if not tr then error("Translit " .. infinitivetr .. " doesn't match Cyrillic " .. infinitive) end end local ending_vowel = usub(ending, 1, 1) local ppptype = data.ppp if com.is_nonsyllabic(stem) then -- e.g. 3b гну́ть (гну́тый); but not -нуть (type 3a, as a suffix) ppptype = "(7)" end if ut.contains({"5a", "5b", "5c"}, data.conj_type) and (ending_vowel == "е" or ending_vowel == "ѣ") then stem, tr = iotated_ppp(data, stem, tr) end if not com.is_stressed(stem) then stem, tr = com.make_ending_stressed(stem, tr) end if data.o then -- цев -> цо́в, e.g. (об)лицева́ть -> (об)лицо́ванный stem = rsub(stem, "е́", "о́") -- Cyrillic if tr then tr = rsub(tr, "e" .. AC, "o" .. AC) -- Latin end elseif data.yo then -- ё occurs with e.g. 1a наверста́ть (навёрстанный) -- ё occurs with e.g. 3b поверну́ть (повёрнутый) -- ё occurs with e.g. 5b лежа́ть (лёжанный) but not with 5c держа́ть -- (де́ржанный) -- ё occurs always with class 2 in -ева́ть, e.g. -- (за)тушева́ть ((за)тушёванный) and (за)клева́ть ((за)клёванный) local subbed stem, subbed = rsubb(stem, "е́", "ё") -- Cyrillic if not subbed and data.old then stem, subbed = rsub(stem, "ѣ́", "ѣ̈") end if not subbed then error("No stressed е" .. (data.old and " or ѣ" or "") .. " in stem " .. stem .. " to replace with ё" .. (data.old and " or ѣ̈" or "") .. " when trying to create participle") end if tr then tr, subbed = rsub(tr, "j[eě]" .. AC, "jo" .. AC) -- Latin if not subbed then tr, subbed = rsub(tr, "[eě]" .. AC, "jo" .. AC) -- Latin end if not subbed then error("No stressed е in translit " .. tr .. " to replace with jo when trying to create participle") end end end if data.conj_type == "1a" and ending_vowel == "е" then -- 1a, only одоле́ть, преодоле́ть, verbs in -печатле́ть set_ppp(forms, stem, tr, "ённый") elseif data.conj_type == "1a" and ending_vowel == "ѣ" then set_ppp(forms, stem, tr, "ѣ̈нный") else local stressed_ending, unstressed_ending if ending_vowel == "е" then stressed_ending = "ённый" unstressed_ending = "енный" elseif ending_vowel == "ѣ" then stressed_ending = "ѣ̈нный" unstressed_ending = "ѣнный" else local ppp_ending = (ending_vowel == "а" or ending_vowel == "я") and "нный" or "тый" stressed_ending = ending_vowel .. AC .. ppp_ending unstressed_ending = ending_vowel .. ppp_ending end set_ppp(forms, stem, tr, -- (7) occurs with 1a обуя́ть (обуя́нный) ppptype == "(7)" and stressed_ending or -- [(7)] -- when does it occur? may only occur in class 4 ppptype == "[(7)]" and {unstressed_ending, stressed_ending} or unstressed_ending) end end -- Iterate over the values of a property (e.g. past_m, past_f), handling -- overrides properly. Call FN on each one, passing in RU, TR, NOTE. local function iterate_over_prop(forms, args, prop, fn) for _, form in ipairs(main_to_all_verb_forms[prop]) do local ru, tr if args[form] then local orig_forms = {} for _, form2 in ipairs(main_to_all_verb_forms[prop]) do if forms[form2] then table.insert(orig_forms, forms[form2]) end end local override = parse_and_stress_override(form, args[form], forms[form], orig_forms) ru, tr = extract_russian_tr(override) end if (not ru or ru == "" or ru == "-") and forms[form] then ru, tr = extract_russian_tr(forms[form]) end -- skip unstressed forms (may occur in the past_m when a stressed -- reflexive -ся́ should occur; these occur only in запереться and -- опереться, where they're used to generate the past active part -- and past adverbial part, and end-stressed forms shouldn't be -- generated) if ru and ru ~= "" and ru ~= "-" and not com.is_unstressed(ru) then local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) end fn(ruentry, trentry, {runotes, trnotes}) end end end -- Set the past passive participle for those classes where it is derived -- from the past tense masculine singular (9, 11, 12, 14, 15, 16). We need -- to apply any relevant overrides. local function set_ppp_from_past_m(forms, args, data) if not data.ppp then return end iterate_over_prop(forms, args, "past_m", function(ru, tr, note) if rfind(ru, "л$") then ru = rsub(ru, "л$", "") if tr then tr = rsub(tr, "l$", "") end end append_ppp(forms, ru, tr, "тый", note) end) end -- Set the past passive participle for class-4 verbs. local function set_class_4_ppp(forms, data, stem, tr, vclass) if not data.ppp then return end local iotated_stem, iotated_tr = iotated_ppp(data, stem, tr) vclass = vclass or data.conj_type if vclass == "4b" then local stressed_iotated_stem, stressed_iotated_tr = com.make_ending_stressed(iotated_stem, iotated_tr) set_ppp(forms, stressed_iotated_stem, stressed_iotated_tr, -- (8) occurs with 4b скрои́ть (скро́енный) data.ppp == "(8)" and "енный" or -- [(8)] occurs with 4b разгроми́ть (разгромлённый, разгро́мленный) data.ppp == "[(8)]" and {"ённый", "енный"} or "ённый") else set_ppp(forms, iotated_stem, iotated_tr, -- (7) occurs with 4c раздели́ть (разделённый) data.ppp == "(7)" and "ённый" or -- [(7)] occurs with 4a осве́домить (осве́домленный, осведомлённый) -- [(7)] occurs with 4c иссуши́ть (иссу́шенный, иссушённый) data.ppp == "[(7)]" and {"енный", "ённый"} or "енный") end end -- Set the past passive participle for class-7 and class-8 verbs. These -- form the PPP by adding to the base of the 3sg pres/futr (i.e. minus -- -ет/-ёт). The stress follows the stress of the past singular feminine. -- Only types a, a(1) and b exist, meaning that if the past singular feminine -- is ending-stressed then the PPP ending is -ённый, otherwise it is -енный -- with the stress of the 3sg pres/futr base preserved (and added to the -- last syllable if the base has no stress, as in 7b укра́сть, 3sg украдёт, -- fem sg past укра́ла, PPP укра́денный). local function set_class_7_8_ppp(forms, args, data) if not data.ppp then return end local sg3_bases = {} -- Extract 3sg bases. There may be more than one possible form, e.g. in -- обокра́сть, so support this. -- FIXME: We don't support checking for overrides here; doing so isn't -- overly hard but is a bit tricky because the overrides will be either -- pres_3sg or futr_3sg, depending on the aspect of the verb. -- FIXME: We don't support manual translit here, because neither 7 nor 8 -- support it elsewhere. for _, form in ipairs(main_to_all_verb_forms["pres_futr_3sg"]) do local ru, tr if forms[form] then ru, tr = extract_russian_tr(forms[form]) end if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) ruentry = rsub(ruentry, "[её]т$", "") if com.is_unstressed(ruentry) then ruentry = com.make_ending_stressed(ruentry) end ut.insert_if_not(sg3_bases, {ruentry, runotes}) end end -- Here we do the same rigmarole as in set_ppp_from_past_m(), to respect -- any past_f overrides that might have been set. It's unlikely that -- there is more than one possible form but we support it. iterate_over_prop(forms, args, "past_f", function(ru, tr, note) for _, base_and_notes in ipairs(sg3_bases) do local base, notes = base_and_notes[1], base_and_notes[2] append_ppp(forms, base, nil, -- check if past_f is ending-stressed rfind(ru, AC .. "$") and "ённый" or "енный", notes) end end) end --[=[ Conjugation functions ]=] conjugations["1a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7", "ё"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) if stem == "-" and not tr then -- Template space; leave it else stem, tr = nom.strip_ending(stem, tr, "ть") end no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "ть") append_participles(forms, stem, tr, "ющий", "емый", "я", "вший", "вши", "в") set_moving_ppp(forms, data) present_je(forms, stem, tr, "a") append_imper(forms, stem, tr, "й", "йте") set_past(forms, stem, tr, "л", "ла", "ло", "ли") return forms end local function guts_of_2(args, data) local forms = {} local inf_stem, inf_tr = nom.split_russian_tr(get_stressed_arg(args, 2)) inf_stem, inf_tr = nom.strip_ending(inf_stem, inf_tr, "ть") no_stray_args(args, 2) local pres_stem, pres_tr = inf_stem, inf_tr local variants = args[1] or "" parse_variants(data, variants, {"+p", "7"}) -- If stem ends in -ева́ть and a past passive participle is called for -- with stress on the -е-, automatically set -о- or -ё- as required. if data.ppp and data.ppp ~= "(7)" then if rfind(inf_stem, "цева́") then if data.ppp == "[(7)]" then -- FIXME. Theoretically we should support this but there -- aren't any verbs requiring it. It won't work properly -- currently because we need the о to appear only when -- stressed. error("Variant [(7)] not supported for class 2") end -- цев -> цо́в, e.g. (об)лицева́ть -> (об)лицо́ванный data.o = true data.title = data.title .. "(-о-)" elseif rfind(inf_stem, "ева́") then data.yo = true data.title = data.title .. "(-ё-)" end end -- all -ова- change to -у- pres_stem = rsub(pres_stem, "о(́?)ва(́?)$", "у%1%2") pres_tr = pres_tr and rsub(pres_tr, "o(́?)va(́?)$", "u%1%2") -- -ева- change to -ю- after most consonants and vowels, to -у- after hissing sounds and ц if rfind(pres_stem, "[бвгдзклмнпрстфхь" .. com.vowel .. AC .. "]е(́?)ва(́?)$") then pres_stem = rsub(pres_stem, "е(́?)ва(́?)$", "ю%1%2") pres_tr = pres_tr and rsub(pres_tr, "e(́?)va(́?)$", "ju%1%2") elseif rfind(pres_stem, "[жцчшщ]е(́?)ва(́?)$") then pres_stem = rsub(pres_stem, "е(́?)ва(́?)$", "у%1%2") pres_tr = pres_tr and rsub(pres_tr, "e(́?)va(́?)$", "u%1%2") end forms["infinitive"] = combine(inf_stem, inf_tr, "ть") if data.conj_type == "2a" then append_participles_2stem(forms, pres_stem, pres_tr, inf_stem, inf_tr, "ющий", "емый", "я", "вший", "вши", "в") present_je(forms, pres_stem, pres_tr, "a") else append_participles_2stem(forms, pres_stem, pres_tr, inf_stem, inf_tr, "ю́щий", "-", "я́", "вший", "вши", "в") present_je(forms, pres_stem, pres_tr, "b") end set_moving_ppp(forms, data) append_imper(forms, pres_stem, pres_tr, "й", "йте") set_past(forms, inf_stem, inf_tr, "л", "ла", "ло", "ли") return forms end conjugations["2a"] = function(args, data) return guts_of_2(args, data) end conjugations["2b"] = function(args, data) return guts_of_2(args, data) end conjugations["3°a"] = function(args, data) local forms = {} -- (5), [(6)] or similar; imperative indicators parse_variants(data, args[1], {"5", "6", "23", "и", "+p", "7", "ё"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = nom.strip_ending(stem, tr, "нуть") local vowel_stem = is_vowel_stem(stem) no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "нуть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "нущий", "-", "-", data.var6 == "req" and "нувший" or data.var6 == "opt" and (vowel_stem and {"вший", "нувший"} or {"ший", "нувший"}) or vowel_stem and "вший" or "ший", data.var6 == "req" and "нувши" or data.var6 == "opt" and (vowel_stem and {"вши", "нувши"} or {"ши", "нувши"}) or vowel_stem and "вши" or "ши", data.var6 == "req" and "нув" or data.var6 == "opt" and (vowel_stem and {"в", "нув"} or "нув") or vowel_stem and "в" or "-") set_moving_ppp(forms, data) present_e_a(forms, stem .. "н", tr and tr .. "n") append_imper_by_variant(forms, stem .. "н", tr and tr .. "n", data.imper_variant, "3°a") forms["past_m"] = data.var5 and combine(stem, tr, "нул") or "-" forms["past_m_short"] = data.var5 ~= "req" and combine(stem, tr, (vowel_stem and "л" or "")) or nil forms["past_f_short"] = combine(stem, tr, "ла") forms["past_n_short"] = combine(stem, tr, "ло") forms["past_pl_short"] = combine(stem, tr, "ли") return forms end conjugations["3a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"23", "и", "+p", "7", "ё"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) -- make sure we can strip нуть from the stem and any translit; nom.strip_ending(stem, tr, "нуть") -- but then just strip the -уть and leave the н stem, tr = nom.strip_ending(stem, tr, "уть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "уть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "ущий", "-", "-", "увший", "увши", "ув") set_moving_ppp(forms, data) present_e_a(forms, stem, tr) append_imper_by_variant(forms, stem, tr, data.imper_variant, "3a") set_past(forms, stem .. "ул", tr and tr .. "ul", "", "а", "о", "и") return forms end local function guts_of_3b_3c(args, data, vclass) local forms = {} parse_variants(data, args[1], {"+p", "7", "ё"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) -- make sure we can strip нуть from the stem and any translit; nom.strip_ending(stem, tr, "ну́ть") -- but then just strip the -у́ть and leave the н stem, tr = nom.strip_ending(stem, tr, "у́ть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "у́ть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "у́щий", "-", "-", "у́вший", "у́вши", "у́в") set_moving_ppp(forms, data) append_imper(forms, stem, tr, "и́", "и́те") set_past(forms, stem, tr, "у́л", "у́ла", "у́ло", "у́ли") if data.conj_type == "3b" then present_e_b(forms, stem, tr) else stem, tr = com.make_ending_stressed(stem, tr) present_e_c(forms, stem, tr) end return forms end conjugations["3b"] = function(args, data) return guts_of_3b_3c(args, data) end conjugations["3c"] = function(args, data) return guts_of_3b_3c(args, data) end conjugations["4a"] = function(args, data) local forms = {} -- imperative variants, also щ, used for verbs like похитить (похи́щу) (4a), -- защитить (защищу́) (4b), поглотить (поглощу́) (4c) with a different -- iotation (т -> щ, not ч) parse_variants(data, args[1], {"23", "и", "щ", "past", "+p", "7", "жд"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = nom.strip_ending(stem, tr, "ить") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "ить") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") append_participles(forms, stem, tr, hushing and "ащий" or "ящий", "awkward-имый", hushing and "а" or "я", "ивший", "ивши", "ив") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "a", data.shch) append_imper_by_variant(forms, stem, tr, data.imper_variant, "4a") -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem .. "и", tr and tr .. "i", args, data) return forms end conjugations["4a1a"] = function(args, data) local forms = {} data.title = "4a // 1a" data.cat_conj_types = {"1a", "4a"} -- imperative variants, also щ, used for verbs like похитить (похи́щу) (4a), -- защитить (защищу́) (4b), поглотить (поглощу́) (4c) with a different -- iotation (т -> щ, not ч) parse_variants(data, args[1], {"23", "и", "щ", "past", "+p", "7", "жд"}) local stem4, tr4 = nom.split_russian_tr(get_stressed_arg(args, 2)) stem4, tr4 = nom.strip_ending(stem4, tr4, "ить") local hushing = rfind(stem4, "[шщжч]$") local stem1, tr1 if hushing then stem1 = stem4 .. "а" tr1 = tr4 and tr4 .. "a" else stem1 = stem4 .. "я" tr1 = tr4 and tr4 .. "ja" end no_stray_args(args, 2) forms["infinitive"] = combine(stem4, tr4, "ить") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. append_participles(forms, stem4, tr4, hushing and "ащий" or "ящий", "awkward-имый", hushing and "а" or "я", "ивший", "ивши", "ив") append_participles(forms, stem1, tr1, "ющий", "емый", "я", {}, {}, {}) set_class_4_ppp(forms, data, stem4, tr4) present_i(forms, stem4, tr4, "a", data.shch) present_je(forms, stem1, tr1, "a", data.shch) append_imper_by_variant(forms, stem4, tr4, data.imper_variant, "4a") append_imper(forms, stem1, tr1, "й", "йте") -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem4 .. "и", tr4 and tr4 .. "i", args, data) return forms end conjugations["4b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"щ", "past", "+p", "8", "жд"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = nom.strip_ending(stem, tr, "и́ть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "и́ть") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") append_participles(forms, stem, tr, hushing and "а́щий" or "я́щий", "awkward-и́мый", hushing and "а́" or "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "b", data.shch) append_imper(forms, stem, tr, "и́", "и́те") -- set prefix to "" as past stem may vary in length and no (1) variants local stem_noa, tr_noa = com.make_unstressed_once(stem, tr) set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "и́", tr_noa and tr_noa .. "i" .. AC, args, data) return forms end conjugations["4c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"щ", "4", "past", "+p", "7", "жд"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = nom.strip_ending(stem, tr, "и́ть") stem, tr = com.make_ending_stressed(stem, tr) no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "и́ть") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") local prap_end_stressed = hushing and "а́щий" or "я́щий" local prap_stem_stressed = hushing and "ащий" or "ящий" append_participles(forms, stem, tr, data.var4 == "req" and prap_stem_stressed or data.var4 == "opt" and {prap_end_stressed, prap_stem_stressed} or prap_end_stressed, "awkward-и́мый", hushing and "а́" or "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "c", data.shch) append_imper(forms, stem, tr, "и́", "и́те") local stem_noa, tr_noa = com.make_unstressed_once(stem, tr) set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "и́", tr_noa and tr_noa .. "i" .. AC, args, data) return forms end -- Combined class 5. But there's enough conditional code that it might make -- more sense to separate them again. local function guts_of_5(args, data) local forms = {} local is5a = data.conj_type == "5a" local is5b = data.conj_type == "5b" -- imperative ending (выгнать - выгони) and past stress; imperative is -- "й" after any vowel (e.g. выстоять), with or without an acute accent, -- otherwise ь or и if is5a or is5b then parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё"}) else parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё", "4"}) end local inf = get_stressed_arg(args, 2) local past_stem = nom.strip_ending(inf, nil, "ть") local stem = is5b and get_opt_unstressed_arg(args, 3) or get_opt_stressed_arg(args, 3) local default_stem = rmatch(past_stem, "^(.*)[еѣая]́?$") if not default_stem then error("Argument " .. inf .. " doesn't end in еть, ѣть, ать or ять") end if not is5a and not is5b then default_stem = com.make_ending_stressed(default_stem) end stem = stem or default_stem local pres_note = stem ~= default_stem and IRREG no_stray_args(args, 3) forms["infinitive"] = past_stem .. "ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") if is5a then append_participles_2stem(forms, stem, nil, past_stem, nil, hushing and "ащий" or "ящий", "имый", hushing and "а" or "я", "вший", "вши", "в", pres_note) elseif is5b then append_participles_2stem(forms, stem, nil, past_stem, nil, hushing and "а́щий" or "я́щий", "и́мый", hushing and "а́" or "я́", "вший", "вши", "в", pres_note) else -- var4 occurs with at least терпре́ть and дыша́ть local prap_end_stressed = hushing and "а́щий" or "я́щий" local prap_stem_stressed = hushing and "ащий" or "ящий" append_participles_2stem(forms, stem, nil, past_stem, nil, data.var4 == "req" and prap_stem_stressed or data.var4 == "opt" and {prap_end_stressed, prap_stem_stressed} or prap_end_stressed, "и́мый", hushing and "а́" or "я́", "вший", "вши", "в", pres_note) end set_moving_ppp(forms, data) present_i(forms, stem, nil, is5a and "a" or is5b and "b" or "c", nil, pres_note) append_imper_by_variant(forms, stem, nil, data.imper_variant, data.conj_type, pres_note) -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, past_stem, nil, args, data) return forms end conjugations["5a"] = function(args, data) return guts_of_5(args, data) end conjugations["5b"] = function(args, data) return guts_of_5(args, data) end conjugations["5c"] = function(args, data) return guts_of_5(args, data) end -- Implement 6a, 6°a, 6a1as13, 6a1as14, and 1a6a. local function guts_of_6a(args, data, vclass) local forms = {} -- Type 6a1a, section 13: -- Forms of both 6a and 1a can occur. They are the same in the infinitive -- and past. In the present active participle and the present/future, the -- type 6 forms are preferred and the type 1a forms are colloquial. In the -- remaining present forms and the imperative, both are equally preferred -- (we put the type-6 forms first because Zaliznyak lists them first). -- Type 6a1a section 14, type 1a6a: -- Forms of both 6a and 1a can occur. They are the same in the infinitive -- and past. In the present adverbial participle and the imperative, the -- type 1a forms are preferred and the type 6a forms are dated. In the -- remaining present forms, one or the other is slightly preferred (type -- 6a for 6a1a, type 1a for 1a6a). if vclass == "6a1as13" or vclass == "6a1as14" then data.title = "6a // 1a" data.cat_conj_types = {"1a", "6a"} elseif vclass == "1a6a" then data.title = "1a // 6a" data.cat_conj_types = {"1a", "6a"} end parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё"}) local inf = get_stressed_arg(args, 2) local inf_past_stem = nom.strip_ending(inf, nil, "ть") local stem = rmatch(inf_past_stem, "^(.*)[ая]́?$") if not stem then error("Argument " .. inf .. " doesn't end in ать or ять") end if com.is_unstressed(stem) then -- колыха́ть, колеба́ть, etc. stem = com.make_ending_stressed(stem) end -- вызвать - вы́зову (в́ызов) local pres_stem = get_opt_stressed_arg(args, 3) or stem no_stray_args(args, 3) local pres_note = pres_stem ~= stem and IRREG -- no iotation, e.g. вырвать - вы́рву local no_iotation = vclass == "6°a" -- replace consonants for 1st person singular present/future local iotated_stem = no_iotation and pres_stem or com.iotation(pres_stem) forms["infinitive"] = inf_past_stem .. "ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") or no_iotation -- Participles -- pres_pasv_part is normal if infinitive ends in -ять, nonexistent except -- with certain lexical exceptions (колеба́ть, колыха́ть, глаго́лать, -- дви́гать with exceptional form дви́жимый) if infinitive ends in -ать local prpp_status = rfind(inf_past_stem, "я́?$") and "" or "none-" if vclass == "6a" or vclass == "6°a" or vclass == "6a1as13" then append_participles_2stem(forms, iotated_stem, nil, inf_past_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", hushing and "а" or "я", "вший", "вши", "в", pres_note) if vclass == "6a1as13" then -- then all the type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий*", prpp_status .. "емый", "я") end elseif vclass == "6a1as14" then -- first the preferred type 6a present active/passive participles append_participles(forms, iotated_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", {}, {}, {}, {}, pres_note) -- then all the type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий", "емый", "я", "вший", "вши", "в") -- then the dated type 6a present adverbial participle append_participles(forms, iotated_stem, nil, {}, {}, hushing and "а*" or "я*", {}, {}, {}, pres_note) else -- type 1a6a -- first the preferred type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий", "емый", "я", "вший", "вши", "в") -- then the type 6a forms (dated in present adverbial participle) append_participles(forms, iotated_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", hushing and "а*" or "я*", {}, {}, {}, pres_note) end set_moving_ppp(forms, data) -- Present/future tense local function class_6_present() if no_iotation then present_e_a(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "a", nil, pres_note) end end if vclass == "6a" or vclass == "6°a" then class_6_present() elseif vclass == "1a6a" then -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a") class_6_present() elseif vclass == "6a1as14" then class_6_present() -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a") else -- 6a1as13 class_6_present() -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a", nil, "*") end -- Imperative forms; if 1a6a or 6a1as14, type 6a forms are dated; -- if 6a1as13, type 6a forms go first. local function class_1_impr() append_imper(forms, inf_past_stem, nil, "й", "йте") end local function class_6_impr() local dated_note = ((vclass == "6a1as14" or vclass == "1a6a") and "*" or "") .. (pres_note or "") append_imper_by_variant(forms, iotated_stem, nil, data.imper_variant, "6a", dated_note) end if vclass == "6a1as14" or vclass == "1a6a" then class_1_impr() class_6_impr() elseif vclass == "6a1as13" then class_6_impr() class_1_impr() else class_6_impr() end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, inf_past_stem, nil, args, data) if vclass == "6a1as14" or vclass == "1a6a" then ut.insert_if_not(data.internal_notes, "* Dated.") elseif vclass == "6a1as13" then ut.insert_if_not(data.internal_notes, "* Colloquial; type-6 forms preferred.") end return forms end conjugations["6a"] = function(args, data) return guts_of_6a(args, data, "6a") end conjugations["6°a"] = function(args, data) return guts_of_6a(args, data, "6°a") end conjugations["6a1as13"] = function(args, data) return guts_of_6a(args, data, "6a1as13") end conjugations["6a1as14"] = function(args, data) return guts_of_6a(args, data, "6a1as14") end conjugations["1a6a"] = function(args, data) return guts_of_6a(args, data, "1a6a") end -- implement 6b, 6°b local function guts_of_6b(args, data, vclass) local forms = {} parse_variants(data, args[1], {"past", "+p", "7", "ё"}) local inf = get_stressed_arg(args, 2) local stem = rmatch(inf, "^(.*)[ая]́ть$") if not stem then error("Argument " .. inf .. " doesn't end in ать or ять") end -- звать - зов, драть - дер local pres_stem = get_opt_unstressed_arg(args, 3) or stem no_stray_args(args, 3) -- no iotation, e.g. рвать - рву local no_iotation = vclass == "6°b" local vowel_end_stem = is_vowel_stem(stem) local pres_note = pres_stem ~= stem and IRREG if no_iotation then present_e_b(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "b", nil, pres_note) end local impr_end = vowel_end_stem and "́й" -- accent on the preceding vowel or "и́" append_imper(forms, pres_stem, nil, impr_end, impr_end .. "те", pres_note) -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(pres_stem, "[шщжч]$") -- no pres_pasv_part local past_stem_with_vowel = stem .. (vowel_end_stem and "я́" or "а́") append_participles_2stem( forms, pres_stem, nil, past_stem_with_vowel, nil, ((hushing or no_iotation) and "у́щий" or "ю́щий"), {}, (hushing and "а́" or "я́"), "вший", "вши", "в", pres_note) forms["infinitive"] = combine(past_stem_with_vowel, nil, "ть") set_moving_ppp(forms, data) -- past_f for ждала́, подождала́ now handled through general mechanism --for разобрало́сь, past_n2 разобрало́ now handled through general mechanism --for разобрали́сь, past_pl2 разобрали́ now handled through general mechanism -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem .. (vowel_end_stem and "я́" or "а́"), nil, args, data) return forms end conjugations["6b"] = function(args, data) return guts_of_6b(args, data, "6b") end conjugations["6°b"] = function(args, data) return guts_of_6b(args, data, "6°b") end -- Implement 6c, 6°c and 6c1a. local function guts_of_6c(args, data, vclass) local forms = {} -- In type 6c1a, forms of both 6c and 1a can occur. They are -- the same in the infinitive and past. In the present active participle -- and the present/future, the type 6c forms are preferred and the type 1a -- forms are colloquial. In the remaining present forms and the imperative, -- both are equally preferred (we put the 6c forms first because Zaliznyak -- lists 6c first). if vclass == "6c1a" then data.title = "6c // 1a" data.cat_conj_types = {"1a", "6c"} end -- optional щ parameter for verbs like клеветать (клевещу́), past stress parse_variants(data, args[1], {"щ", "past", "+p", "7", "ё"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "а́ть") stem = com.make_ending_stressed(stem) -- разостла́ть - расстелю́, рассте́лешь local pres_stem = get_opt_stressed_arg(args, 3) or stem no_stray_args(args, 3) local pres_note = pres_stem ~= stem and IRREG -- remove accent for some forms local stem_noa = com.make_unstressed(stem) -- applies only to стона́ть, застона́ть, простона́ть local no_iotation = vclass == "6°c" -- iotate the stem local iotated_stem = no_iotation and pres_stem or com.iotation(pres_stem, nil, data.shch) local stem1a = stem_noa .. "а́" forms["infinitive"] = stem_noa .. "а́ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") -- Participles append_participles_2stem(forms, iotated_stem, nil, stem_noa, nil, (hushing or no_iotation) and "ущий" or "ющий", {}, hushing and "а́" or "я́", "а́вший", "а́вши", "а́в", pres_note) if vclass == "6c1a" then -- then all the type 1a forms (both are the same in the past) append_participles(forms, stem1a, nil, "ющий*", "емый", "я") end set_moving_ppp(forms, data) if no_iotation then present_e_c(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "c", data.shch, pres_note) end append_imper(forms, iotated_stem, nil, "и́", "и́те", pres_note) if vclass == "6c1a" then present_je(forms, stem1a, nil, "a", nil, "*") append_imper(forms, stem1a, nil, "й", "йте") end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "а́", nil, args, data) if vclass == "6c1a" then ut.insert_if_not(data.internal_notes, "* Colloquial; type-6 forms preferred.") end return forms end conjugations["6c"] = function(args, data) return guts_of_6c(args, data, "6c") end conjugations["6°c"] = function(args, data) return guts_of_6c(args, data, "6°c") end conjugations["6c1a"] = function(args, data) return guts_of_6c(args, data, "6c1a") end local function convert_last_e_to_yo(form) return rsub(form, "([еѣ])́?([^" .. com.vowel .. "]*)$", function(e, nonvowels) return (e == "е" and "ё" or "ѣ̈") .. nonvowels end) end local function guts_of_7(args, data, forms) local is7b = data.conj_type == "7b" local full_inf = get_stressed_arg(args, 2) local pres_stems = is7b and get_unstressed_arg(args, 3) or get_stressed_arg(args, 3) pres_stems = rsplit(pres_stems, ",") local past_stem if past_stem ~= "ёе" then past_stem = get_opt_stressed_arg(args, 4) end local past_stem_vowel_alt = past_stem == "ёе" if past_stem_vowel_alt then past_stem = nil end no_stray_args(args, 4) forms["infinitive"] = full_inf -- Construct the default past and present stem by a combination of -- infinitive and present final consonant. -- (1) Deduce the final consonant. local final_cons for _, pres_stem in ipairs(pres_stems) do -- Final cons is -ст if pres stem ends in vowel + ст, else -- single final cons [дтсзбп] (no actual examples of final п). -- Note that final -з can occur after a consonant (e.g. ползти́). local this_final_cons = rmatch(pres_stem, "[" .. com.vowel .. "]" .. AC .. "?(ст)$") if not this_final_cons then this_final_cons = rmatch(pres_stem, "([дтсзбп])$") end if not this_final_cons then error("Unable to determine final consonant from present stem " .. pres_stem) end if final_cons and this_final_cons ~= final_cons then error("Present stems with conflicting final consonants specified: " .. table.concat(pres_stems, ",")) end final_cons = this_final_cons end -- (2) Find the infinitive minus the termination. local prefix = rmatch(full_inf, "^(.*)[сз]т[иь]" .. AC .."?$") if not prefix then error("Strange infinitive " .. full_inf .. "in class 7") end -- (3) Combine infinitive with final consonant. local default_pres_stem = prefix .. final_cons if is7b then default_pres_stem = com.make_unstressed(default_pres_stem) end local default_past_stem = default_pres_stem if com.is_unstressed(default_past_stem) then default_past_stem = com.make_ending_stressed(default_past_stem) end -- (4) Past stems ending in -д and -т when the infinitive ends in -сть (but not -сти or -сти́) -- lose this consonant (page 85 of Zaliznyak, see also footnote 2 on that page). if rfind(full_inf, "сть$") then default_past_stem = rsub(default_past_stem, "[дт]$", "") end -- (5) If 7b and the past stem wasn't originally specified as ёе, the past stem gets -- ё in place of е. if is7b and not past_stem_vowel_alt then default_past_stem = convert_last_e_to_yo(default_past_stem) end for _, pres_stem in ipairs(pres_stems) do local pres_note = pres_stem ~= default_pres_stem and IRREG if is7b then present_e_b(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и́", "и́те", pres_note) else present_e_a(forms, pres_stem, nil, pres_note) append_imper_by_variant(forms, pres_stem, nil, data.imper_variant, "7a", pres_note) end end -- Construct the past stem if not specified. Note that we then derive a separate -- past-tense stem from this stem, and this stem as such ends up applying only -- to the past active and adverbial participles. if not past_stem then past_stem = default_past_stem end local past_note = past_stem ~= default_past_stem and IRREG -- Derive the past tense stem from the past stem derived above. This has ё instead of е -- in 7b verbs; it also loses д and т in all cases, when the past stem derived above only loses -- these consonants in some cases. local past_tense_stem = past_stem if is7b then past_tense_stem = convert_last_e_to_yo(past_tense_stem) end past_tense_stem = rsub(past_tense_stem, "[дт]$", "") local vowel_pp = is_vowel_stem(past_stem) local pap = vowel_pp and "вши" or "ши" local var9_note_symbol = next_note_symbol(data) for _, pres_stem in ipairs(pres_stems) do append_participles_2stem(forms, pres_stem, nil, past_stem, nil, is7b and "у́щий" or "ущий", "-", is7b and "я́" or "я", vowel_pp and "вший" or "ший", data.var9 and {is7b and "я́" or "я", pap .. var9_note_symbol} or pap, vowel_pp and not data.var9 and "в" or "-", pres_note, past_note) end if data.var9 then ut.insert_if_not(data.internal_notes, var9_note_symbol .. " Dated.") end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, past_tense_stem, nil, args, data, -- 0 ending if the past stem ends in a consonant not is_vowel_stem(past_tense_stem) and "no-pastml", past_note) -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) end conjugations["7a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"23", "и", "9","past", "+p"}) -- лезть - ле́зши - non-existent past_actv_part handled through general mechanism guts_of_7(args, data, forms) return forms end conjugations["7b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"9", "past", "+p"}) guts_of_7(args, data, forms) return forms end local function class_8a_stem_to_infinitive(stem) -- map e.g. вы́сек back to высе́чь return rsub(stem, "[гк]$", "чь") end local function class_8b_stem_to_infinitive(stem) -- map e.g. отвлёк back to отвле́чь -- map e.g. зажёг back to заже́чь return com.make_ending_stressed(rsub(rsub(rsub(stem, "ё", "е"), "ѣ̈", "ѣ"), "[гк]$", "чь")) end conjugations["8a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local full_inf = get_stressed_arg(args, 2) local stem = get_stressed_arg(args, 3) local stressed_past_stem = get_opt_stressed_arg(args, 4) or stem no_stray_args(args, 4) forms["infinitive"] = full_inf local pres_note = class_8a_stem_to_infinitive(stem) ~= full_inf and IRREG local stressed_past_note = class_8a_stem_to_infinitive(stressed_past_stem) ~= full_inf and IRREG -- default for pres_pasv_part is blank append_participles_2stem(forms, stem, nil, stressed_past_stem, nil, "ущий", "-", "-", "ший", "ши", "-", pres_note, stressed_past_note) local iotated_stem = com.iotation(stem) append_pres_futr(forms, iotated_stem, nil, {}, "ешь", "ет", "ем", "ете", {}, pres_note) append_pres_futr(forms, stem, nil, "у", {}, {}, {}, {}, "ут", pres_note) append_imper(forms, stem, nil, "и", "ите", pres_note) -- set prefix to "" as stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem, nil, args, data, "no-pastml", pres_note) forms["past_m"] = stressed_past_stem .. (stressed_past_note or "") -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) return forms end conjugations["8b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local full_inf = get_stressed_arg(args, 2) local stem = get_unstressed_arg(args, 3) local stressed_past_stems = rsplit(args[4] or "ё", ",") for _, stressed_past_stem in ipairs(stressed_past_stems) do if stressed_past_stem ~= "е" then check_stressed_arg(stressed_past_stem, 4) end end no_stray_args(args, 4) forms["infinitive"] = full_inf local pres_note = class_8b_stem_to_infinitive(stem) ~= full_inf and IRREG local iotated_stem = com.iotation(stem) append_pres_futr(forms, iotated_stem, nil, {}, "ёшь", "ёт", "ём", "ёте", {}, pres_note) append_pres_futr(forms, stem, nil, "у́", {}, {}, {}, {}, "у́т", pres_note) append_imper(forms, stem, nil, "и́", "и́те", pres_note) -- set prefix to "" as stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, com.make_ending_stressed(stem), nil, args, data, "no-pastml", pres_note) forms["past_m"] = nil for _, stressed_past_stem in ipairs(stressed_past_stems) do local pastm_stem, past_part_stem if stressed_past_stem == "е" then past_part_stem = com.make_ending_stressed(stem) pastm_stem = past_part_stem elseif stressed_past_stem == "ё" then past_part_stem = convert_last_e_to_yo(com.make_ending_stressed(stem)) pastm_stem = past_part_stem elseif stressed_past_stem == "ёе" then past_part_stem = com.make_ending_stressed(stem) pastm_stem = convert_last_e_to_yo(past_part_stem) else pastm_stem = stressed_past_stem past_part_stem = stressed_past_stem end local past_note = class_8b_stem_to_infinitive(pastm_stem) ~= full_inf and IRREG -- default for pres_pasv_part is blank; влечь -> влеко́мый handled through -- general override mechanism append_participles_2stem(forms, stem, nil, past_part_stem, nil, "у́щий", "-", "-", "ший", "ши", "-", pres_note, past_note) append_form(forms, "past_m", pastm_stem, nil, "", past_note) end -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) return forms end conjugations["9a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "еть") local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) local default_pres_stem = prefix .. rsub(base, "е", "") pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem .. "еть" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "ший", "ши", "ев") present_e_a(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и", "ите", pres_note) -- past_m doesn't end in л set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data, "no-pastml") set_ppp_from_past_m(forms, args, data) return forms end conjugations["9b"] = function(args, data) local forms = {} --for this type, it's important to distinguish impf and pf local impf = rfind(data.verb_type, "^impf") parse_variants(data, args[1], {"past", "+p", "*"}) local stem_noa = nom.strip_ending(get_stressed_arg(args, 2), nil, "е́ть") local stem = rsub(stem_noa, "(.*)е", "%1ё") local pres_stem = get_opt_unstressed_arg(args, 3) -- stem used for past active and adverbial participles; defaults to past_m local past_part_stem = get_opt_stressed_arg(args, 4) no_stray_args(args, 4) local prefix, _, base, _ = split_monosyllabic_main_verb(stem, nil, "single_cons_base") local default_pres_stem = data.star and construct_long_prefix_variant(prefix) .. rsub(base, "[её]", "") or prefix .. rsub(base, "[её]", "") pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem_noa .. "е́ть" present_e_b(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и́", "и́те", pres_note) -- past_m doesn't end in л set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data, "no-pastml") set_ppp_from_past_m(forms, args, data) append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", {}, {}, -- impf: тереть -> тёрши -- pf: растереть -> растёрши, растере́в -- we handle (рас)тёрши down below because the stress depends on the -- past_m: запереть -> за́пер, за́перши(й) {}, {}, impf and {} or "е́в", pres_note) if past_part_stem then for _, ppstem in ipairs(rsplit(past_part_stem, ",")) do append_participles(forms, ppstem, nil, {}, {}, {}, "ший", "ши", {}) end else iterate_over_prop(forms, args, "past_m", function(ru, tr, note) append_participles(forms, ru, tr, {}, {}, {}, "ший", "ши", {}, note) end) end return forms end conjugations["10a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "оть") no_stray_args(args, 2) forms["infinitive"] = stem .. "оть" -- These verbs are perfective-only, no present participles append_participles(forms, stem, nil, "-", "-", "-", "овший", "овши", "ов") set_moving_ppp(forms, data) present_je(forms, stem, nil, "a") append_imper(forms, stem, nil, "и", "ите") set_past(forms, stem .. "ол", nil, "", "а", "о", "и") return forms end conjugations["10c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7"}) local inf_stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") -- present tense stressed stem "моло́ть" - ме́лет local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = com.make_ending_stressed(nom.strip_ending(inf_stem, nil, "о́")) pres_stem = pres_stem or default_pres_stem -- remove accent for some forms local pres_stem_noa = com.remove_accents(pres_stem) local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = inf_stem .. "ть" -- default for pres_pasv_part is blank append_participles_2stem(forms, pres_stem, nil, inf_stem, nil, "ющий", "-", "я́", "вший", "вши", "в", pres_note) set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "c", nil, pres_note) append_imper(forms, pres_stem_noa, nil, "и́", "и́те", pres_note) set_past(forms, inf_stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["11a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ить") no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem .. "и") forms["infinitive"] = stem .. "ить" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "ивший", "ивши", "ив") present_je(forms, stem .. "ь", nil, "a") append_imper(forms, stem .. "ей", nil, "", "те") set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["11b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p", "*"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "и́ть") local pres_stem = get_opt_unstressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem .. "и́", nil, "single_cons_base") local default_pres_stem = data.star and construct_long_prefix_variant(prefix) .. rsub(base, "и́$", "") or stem pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem .. "и́ть" append_participles_2stem(forms, pres_stem, nil, stem, nil, "ью́щий", "-", "ья́", "и́вший", "и́вши", "и́в", pres_note) present_je(forms, pres_stem .. "ь", nil, "b", nil, pres_note) append_imper(forms, stem .. "е́й", nil, "", "те") -- e.g. пила́, лила́ set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["12a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = stem pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" append_participles_2stem(forms, pres_stem, nil, stem, nil, "ющий", "емый", "я", "вший", "вши", "в", pres_note) present_je(forms, pres_stem, nil, "a", nil, pres_note) append_imper(forms, pres_stem .. "й", nil, "", "те", pres_note) set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["12b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_opt_unstressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = com.make_unstressed_once(stem) pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "ю́щий", "-", "я́", "вший", "вши", "в", pres_note) present_je(forms, pres_stem, nil, "b", nil, pres_note) -- the preceding vowel is stressed append_imper(forms, pres_stem .. "́й", nil, "", "те", pres_note) -- e.g. гнила́ but пе́ла set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["13b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = nom.strip_ending(stem, nil, "ва́") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- tricky to use append_participles_2stem() because only pres_actv_part -- uses pres_stem, not all present participles forms["pres_actv_part"] = pres_stem .. "ю́щий" forms["pres_pasv_part"] = stem .. "емый" forms["pres_adv_part"] = stem .. "я" forms["past_actv_part"] = stem .. "вший" forms["past_adv_part"] = stem .. "вши" forms["past_adv_part_short"] = stem .. "в" set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "b") forms["impr_sg"] = stem .. "й" forms["impr_pl"] = stem .. "йте" set_past(forms, stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["14a"] = function(args, data) -- only one verb: вы́жать local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_stressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "вший", "вши", "в") present_e_a(forms, pres_stem) forms["impr_sg"] = pres_stem .. "и" forms["impr_pl"] = pres_stem .. "ите" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["14b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_unstressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_b(forms, pres_stem) forms["impr_sg"] = pres_stem .. "и́" forms["impr_pl"] = pres_stem .. "и́те" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["14c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_stressed_arg(args, 3) local pres_stem_noa = com.make_unstressed(pres_stem) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_c(forms, pres_stem) forms["impr_sg"] = pres_stem_noa .. "и́" forms["impr_pl"] = pres_stem_noa .. "и́те" --two forms for past_m: при́нялся, приня́лся --изъя́ла but приняла́ set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["15a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, stem, nil, "нущий", "-", "-", "вший", "вши", "в") present_e_a(forms, stem .. "н") forms["impr_sg"] = stem .. "нь" forms["impr_pl"] = stem .. "ньте" set_past(forms, stem .. "л", nil, "", "а", "о", "и") set_ppp_from_past_m(forms, args, data) return forms end conjugations["16a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, stem, nil, "ву́щий", "-", "-", "вший", "вши", "в") present_e_a(forms, stem .. "в") forms["impr_sg"] = stem .. "ви" forms["impr_pl"] = stem .. "вите" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["16b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local stem_noa = com.make_unstressed(stem) no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles(forms, stem, nil, "ву́щий", "-", "вя́", "вший", "вши", "в") present_e_b(forms, stem_noa .. "в") forms["impr_sg"] = stem_noa .. "ви́" forms["impr_pl"] = stem_noa .. "ви́те" -- e.g. прижило́сь, прижи́лось set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg"] = function(args, data) local prefix, _, main = split_known_main_verb(get_stressed_arg(args, 2), -- честь must go before есть {"бежа́ть", "бѣжа́ть", "хоте́ть", "хотѣ́ть", "да́ть", "че́сть", "е́сть", "ѣ́сть", "сы́пать", "лга́ть", "мо́чь", "идти́", "йти́", "е́хать", "ѣ́хать", "мину́ть", "живописа́ть", "ле́чь", "зи́ждить", "зы́бить", "кля́сть", "стели́ть", "бы́ть", "сса́ть", "сца́ть", "чти́ть", "шиби́ть", "реве́ть", "има́ть", "вня́ть", "обя́зывать"}) main = com.make_unstressed_once(main) if not conjugations["irreg-" .. main] then error("Strange, can't find conjugation for main verb " .. main) end return conjugations["irreg-" .. main](args, data) end conjugations["irreg-бежать"] = function(args, data) -- irregular, only for verbs derived from бежать with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"бежа́ть", "бѣжа́ть"}) data.title = com.is_stressed(prefix) and "5a" or "5b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "бежа́ть" append_participles_2stem(forms, "бег", nil, "бежа́", nil, "у́щий", "-", "-", "вший", "вши", "в", IRREG) append_imper(forms, "беги́", nil, "", "те", IRREG) append_pres_futr(forms, "бе", nil, "гу́" .. IRREG, "жи́шь", "жи́т", "жи́м", "жи́те", "гу́т" .. IRREG) set_past(forms, "бежа́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^бе", "бѣ") end prepend_prefix(forms, prefix) -- no PPP's for any derivatives of бежать return forms end conjugations["irreg-бѣжать"] = conjugations["irreg-бежать"] conjugations["irreg-хотеть"] = function(args, data) -- irregular, only for verbs derived from хотеть with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"хоте́ть", "хотѣ́ть"}) data.title = "5c'" data.cat_conj_types = {"5c"} -- no class for 5c', no point in creating for just this verb -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "хоте́ть" append_participles_2stem(forms, "хот", nil, "хоте́", nil, "я́щий", "-", "я́", "вший", "вши", "в") append_imper(forms, "хоти́", nil, "", "те") append_pres_futr(forms, "", nil, "хочу́", "хо́чешь" .. IRREG, "хо́чет" .. IRREG, "хоти́м", "хоти́те", "хотя́т") set_past(forms, "хоте́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^хоте", "хотѣ") end prepend_prefix(forms, prefix) return forms end conjugations["irreg-хотѣть"] = conjugations["irreg-хотеть"] conjugations["irreg-дать"] = function(args, data) -- irregular, only for verbs derived from дать with the same stress pattern and вы́дать local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "да́ть") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "да́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "", nil, "даю́щий", "-", "-", "да́вший", "да́вши", "да́в") append_imper(forms, "да́й", nil, "", "те") append_pres_futr(forms, "", nil, "да́м", "да́шь", "да́ст", "дади́м", "дади́те", "даду́т") prepend_prefix(forms, prefix) set_past_by_stress(forms, data.past_stress, prefix, nil, "да́", nil, args, data) if data.ppp then if prefix == "пере" then set_ppp(forms, "", nil, "пе́реданный") elseif prefix == "раз" then set_ppp(forms, "", nil, "ро́зданный") else set_moving_ppp(forms, data) end end return forms end conjugations["irreg-есть"] = function(args, data) -- irregular, only for verbs derived from есть local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"е́сть", "ѣ́сть"}) data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "е́сть" append_participles_2stem(forms, "ед", nil, "е́", nil, "я́щий", "о́мый", "я́", "вший", "вши", "в") if data.ppp then set_ppp(forms, "е́д", nil, "енный") end append_imper(forms, "е́шь", nil, "", "те") append_pres_futr(forms, "е́", nil, "м", "шь", "ст", "ди́м", "ди́те", "дя́т") set_past(forms, "е́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^е", "ѣ") end prepend_prefix(forms, prefix) return forms end conjugations["irreg-ѣсть"] = conjugations["irreg-есть"] conjugations["irreg-сыпать"] = function(args, data) -- irregular, only for verbs derived from сыпать local forms = {} --for this type, it's important to distinguish if it's reflexive for вы́сыпаться vs. вы́сыпать imperative local prefix = split_known_main_verb(get_stressed_arg(args, 2), "сы́пать") data.title = "6a" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "сы́пать" append_participles(forms, "сы́п", nil, "лющий", "лемый", {"ля", "я" .. IRREG}, "авший", "авши", "ав") append_imper(forms, "сы́п", nil, -- вы́сыпать (but not вы́сыпаться) has two imperative singulars com.is_stressed(prefix) and not data.refl and {"и", "ь"} or "ь", "ьте", IRREG) present_je(forms, "сы́пл", nil, "a") append_pres_futr(forms, "сы́п", nil, {}, "ешь", "ет", "ем", "ете", {}, IRREG) set_past(forms, "сы́пал", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-лгать"] = function(args, data) -- irregular, only for verbs derived from лгать with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "лга́ть") data.title = "6°b/c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "лга́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "лг", nil, "у́щий", "-", "-", "а́вший", "а́вши", "а́в") append_imper(forms, "лги́", nil, "", "те") append_pres_futr(forms, "", nil, "лгу́", "лжёшь" .. IRREG, "лжёт" .. IRREG, "лжём" .. IRREG, "лжёте" .. IRREG, "лгу́т") set_past(forms, "лга́л", nil, "", "а́", "о", "и") prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-мочь"] = function(args, data) -- irregular, only for verbs derived from мочь with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "мо́чь") data.title = "8c/b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "мо́чь" -- no passive or adverbial participles append_participles(forms, "мо́г", nil, "у́щий", "-", "-", "ший", "-", "-") append_imper(forms, "моги́", nil, "", "те") append_pres_futr(forms, "", nil, "могу́", "мо́жешь", "мо́жет", "мо́жем", "мо́жете", "мо́гут") set_past(forms, "мо́г", nil, "", "ла́", "ло́", "ли́") prepend_prefix(forms, prefix) return forms end conjugations["irreg-идти"] = function(args, data) -- irregular, only for verbs derived from идти, including прийти́ and в́ыйти local forms = {} local prefix = args[2] == "идти́" and "" or split_known_main_verb(get_stressed_arg(args, 2), "йти́") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b/b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no pres_pasv_part if prefix == "" then -- only идти, present imperfective forms["infinitive"] = "идти́" append_imper(forms, "иди́", nil, "", "те") present_e_b(forms, "ид") -- no past_adv_part_short append_participles(forms, "", nil, "иду́щий", "-", "идя́", "ше́дший", "ше́дши", "-") elseif rfind(prefix, "и$") then -- при forms["infinitive"] = "йти́" append_imper(forms, "ди́", nil, "", "те") present_e_b(forms, "д") append_participles(forms, "", nil, "-", "-", "-", "ше́дший", "ше́дши", "дя́") else forms["infinitive"] = "йти́" append_imper(forms, "йди́", nil, "", "те") present_e_b(forms, "йд") append_participles(forms, "", nil, "-", "-", "-", "ше́дший", "ше́дши", "йдя́") end set_past(forms, "", nil, "шёл", "шла́", "шло́", "шли́") prepend_prefix(forms, prefix) if data.ppp then if prefix == "на" or prefix == "про" then -- найти́ and пройти́ exceptionally have the stress on the prefix set_ppp(forms, prefix, nil, "́йденный") else -- вы́йти and прийти́ are intransitive so we don't have to worry about them set_ppp(forms, prefix, nil, "йдённый") end end return forms end conjugations["irreg-йти"] = conjugations["irreg-идти"] conjugations["irreg-ехать"] = function(args, data) -- irregular, only for verbs derived from ехать local forms = {} local old = data.old local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"е́хать", "ѣ́хать"}) data.title = "irreg-a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "е́хать" -- no pres_pasv_part -- no pres_adv_part append_participles_2stem(forms, "е́д", nil, "е́х", nil, "ущий", "-", "-", "авший", "авши", "ав") present_e_a(forms, "е́д") set_past(forms, "е́хал", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^е", "ѣ") end prepend_prefix(forms, prefix) --special-case the imperative --literary (special) imperative forms for ехать are поезжа́й, поезжа́йте impstem = data.old and "ѣзжа́й" or "езжа́й" if prefix == "" then append_imper(forms, "по" .. impstem, nil, "", "те") append_imper(forms, impstem, nil, "", "те") elseif com.is_stressed(prefix) then append_imper(forms, com.make_unstressed_once(prefix) .. impstem, nil, "", "те") else append_imper(forms, prefix .. impstem, nil, "", "те") end return forms end conjugations["irreg-ѣхать"] = conjugations["irreg-ехать"] conjugations["irreg-минуть"] = function(args, data) -- for the irregular verb "мину́ть" local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "мину́ть") data.title = "3c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "мину́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "ми́н", nil, "у́щий", "-", "-", "у́вший", "у́вши", "у́в") present_e_c(forms, "ми́н") forms["pres_futr_1sg"] = "-" -- no futr 1sg -- no imperative -- two possible variants, one with root-only stress, the other with -- either root or suffix stress. if not args["root_past_stress"] then append_past(forms, "мину́л", nil, "", "а", "о", "и") end append_past(forms, "ми́нул", nil, "", "а", "о", "и", IRREG) prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-живописать"] = function(args, data) -- for irregular verb "живописа́ть", mixture of types 1 and 2 local forms = {} local inf = get_stressed_arg(args, 2) data.title = "1a" parse_variants(data, args[1], {"+p"}) local inf_stem = nom.strip_ending(inf, nil, "ть") local pres_stem = rfind(inf_stem, "а́$") and rsub(inf_stem, "а́$", "у́") or error("Unexpected infinitive " .. inf) no_stray_args(args, 2) forms["infinitive"] = inf_stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, inf_stem, nil, "ющий", "-", "я", "вший", "вши", "в", IRREG) set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "a", nil, IRREG) append_imper(forms, pres_stem .. "й", nil, "", "те", IRREG) set_past(forms, inf_stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["irreg-лечь"] = function(args, data) -- irregular, only for verbs derived from лечь with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "ле́чь") data.title = "8a/b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "ле́чь" -- no pres parts because always perfective -- no past_adv_part_short append_participles(forms, "лёг", nil, "-", "-", "-", "ший", "ши", "-") append_imper(forms, "ля́г", nil, "", "те", IRREG) append_pres_futr(forms, "ля́", nil, "гу", "жешь", "жет", "жем", "жете", "гут", IRREG) set_past(forms, "", nil, "лёг", "легла́", "легло́", "легли́") prepend_prefix(forms, prefix) return forms end conjugations["irreg-честь"] = function(args, data) -- irregular, only for verbs derived from идти, including прийти́ and в́ыйти local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "че́сть") local pre_two_cons_prefix = prefix == "об" and "обо" or prefix == "с" and "со" or prefix == "рас" and "разо" or prefix data.title = prefix == "" and "7b/b" or com.is_stressed(prefix) and "7a⑨" or pre_two_cons_prefix ~= prefix and "7*b/b⑨" or "7b/b⑨" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no pres_pasv_part forms["infinitive"] = "че́сть" append_imper(forms, "чти́", nil, "", "те", IRREG) present_e_b(forms, "чт", nil, IRREG) if prefix == "" then append_participles(forms, "", nil, "чту́щий", "-", "чтя́", "чти́вший", "чти́вши", "чти́в", IRREG) elseif com.is_stressed(prefix) then append_participles(forms, "", nil, "-", "-", "-", "-", "чтя́", "-", IRREG) else append_participles(forms, "", nil, "-", "-", "-", "-", {"чтя́" .. IRREG, "чётши*"}, "-") ut.insert_if_not(data.internal_notes, "* Dated.") end if data.ppp then set_ppp(forms, "", nil, "чтённый" .. IRREG) end set_past(forms, "", nil, "чёл", "чла́" .. IRREG, "чло́" .. IRREG, "чли́" .. IRREG) prepend_prefix(forms, prefix, pre_two_cons_prefix) return forms end conjugations["irreg-зиждить"] = function(args, data) -- irregular, only for verbs derived from зиждить(ся) with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "зи́ждить") data.title = "irreg-a" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "зи́ждить" append_participles(forms, "зи́жд", nil, "ущий", "емый", "я", "ивший", "ивши", "ив") if data.ppp then set_ppp(forms, "зи́жд", nil, "енный") end append_imper(forms, "зи́жди", nil, "", "те") present_e_a(forms, "зи́жд") set_past(forms, "зи́ждил", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-зыбить"] = function(args, data) -- irregular, only for verbs derived from зыбить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "зы́бить") data.title = "irreg-a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "зы́бить" append_participles(forms, "зы́б", nil, "лющий", "лемый", "ля", "ивший", "ивши", "ив") append_imper(forms, "зы́бли", nil, "", "те") present_je(forms, "зы́б", nil, "a") set_past(forms, "зы́бил", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-клясть"] = function(args, data) -- irregular, only for verbs derived from клясть with the same stress pattern local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "кля́сть") data.title = "irreg-b" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "кля́сть" append_participles_2stem(forms, "клян", nil, "кля́", nil, "у́щий", "и́мый", "я́", "вший", "вши", "в") append_imper(forms, "кляни́", nil, "", "те") present_e_b(forms, "клян") prepend_prefix(forms, prefix) set_past_by_stress(forms, data.past_stress, prefix, nil, "кля́", nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg-стелить"] = function(args, data) -- irregular, only for verbs derived from стелить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "стели́ть") data.title = com.is_stressed(prefix) and "4a" or "4c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "стели́ть" append_participles(forms, "сте́л", nil, "ющий" .. IRREG, "и́мый", "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, "сте́л", nil, data.title) append_imper(forms, "стели́", nil, "", "те") append_pres_futr(forms, "сте́л", nil, "ю́", {}, {}, {}, {}, {}) append_pres_futr(forms, "сте́л", nil, {}, "ешь", "ет", "ем", "ете", "ют", IRREG) set_past(forms, "стели́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-быть"] = function(args, data) -- irregular, only for verbs derived from быть with various stress patterns, the actual verb быть different from its derivatives local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "бы́ть") data.title = "irreg-a" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "бы́ть" -- no pres_pasv_part append_participles(forms, "", nil, "су́щий", "-", "бу́дучи", "бы́вший", "бы́вши", "бы́в") append_imper(forms, "бу́дь", nil, "", "те") prepend_prefix(forms, prefix) -- only for "бы́ть", some forms are archaic if forms["infinitive"] == "бы́ть" then append_pres_futr(forms, "", nil, "есть", "есть", "есть", "есть", "есть", "есть") elseif com.is_stressed(prefix) then -- if the prefix is stressed, e.g. "вы́быть" present_e_a(forms, prefix .. "буд") else present_e_a(forms, prefix .. "бу́д") end set_past_by_stress(forms, data.past_stress, prefix, nil, "бы́", nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg-ссать-сцать"] = function(args, data) -- irregular, only for verbs derived from ссать and сцать (both vulgar!) local forms = {} local prefix, _, stem = split_known_main_verb(get_stressed_arg(args, 2), {"сса́ть", "сца́ть"}) data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) stem = nom.strip_ending(stem, nil, "ть") local pres_stem = rsub(stem, "а́?$", "") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, pres_stem, nil, "у́щий", "-", "-", "а́вший", "а́вши", "а́в") append_imper(forms, pres_stem, nil, "ы́", "ы́те") append_pres_futr(forms, pres_stem, nil, "у́", "ы́шь", "ы́т", "ы́м", "ы́те", "у́т") set_past(forms, stem .. "л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-ссать"] = conjugations["irreg-ссать-сцать"] conjugations["irreg-сцать"] = conjugations["irreg-ссать-сцать"] conjugations["irreg-чтить"] = function(args, data) -- irregular, only for verbs derived from чтить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "чти́ть") data.title = "4b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "чти́ть" append_participles_2stem(forms, "чт", nil, "чти́", nil, {"я́щий", "у́щий" .. IRREG}, "и́мый", "я́", "вший", "вши", "в") if data.ppp then set_ppp(forms, "чт", nil, "ённый") end append_imper(forms, "чти́", nil, "", "те") append_pres_futr(forms, "чт", nil, "у́" .. IRREG, "и́шь", "и́т", "и́м", "и́те", {"я́т", "у́т" .. IRREG}) set_past(forms, "чти́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-шибить"] = function(args, data) -- irregular, only for verbs in -шибить(ся) local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "шиби́ть") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no present participles forms["infinitive"] = "шиби́ть" append_participles(forms, "шиби́", nil, "-", "-", "-", "вший", "вши", "в") if data.ppp then set_ppp(forms, "ши́бл", nil, "енный") end append_imper(forms, "шиби́", nil, "", "те") present_e_b(forms, "шиб") set_past(forms, "ши́б", nil, "", "ла", "ло", "ли") prepend_prefix(forms, prefix) return forms end conjugations["irreg-реветь"] = function(args, data) -- irregular, only for verbs derived from "реветь" local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "реве́ть") data.title = "irreg-b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "реве́ть" -- no pres_pasv_part append_participles_2stem(forms, "рев", nil, "реве́", nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_b(forms, "рев") append_imper(forms, "реви́", nil, "", "те") set_past(forms, "реве́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-имать"] = function(args, data) -- irregular, only for внимать and certain archaic verbs (e.g. имать as -- conjugated in the 18th century, отъимать) local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "има́ть") data.title = "1a // 6a" data.cat_conj_types = {"1a", "6a"} parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "има́ть" -- handle внемл- forms append_participles(forms, "е́мл", nil, "ющий", "емый", {"я", "я́"}, {}, {}, {}) -- handle внима́- forms append_participles(forms, "има́", nil, "ющий", "емый", "я", "вший", "вши", "в") if data.ppp then -- FIXME, do class-1a-type ppp's (e.g. вни́манный) exist? -- ruwikt marks them with a * set_ppp(forms, "е́мл", nil, "енный") end append_imper(forms, "", nil, {"е́мли", "емли́", "има́й"}, {"е́млите", "емли́те", "има́йте"}) present_je(forms, "е́мл", nil, "a") -- Both вне́млю and внемлю́ are possible append_pres_futr(forms, "емл", nil, "ю́", {}, {}, {}, {}, {}) present_je(forms, "има́", nil, "a") set_past(forms, "има́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-внять"] = function(args, data) -- irregular, only for внять local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "вня́ть") data.title = "14c/c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "вня́ть" -- perfective only; no present participles append_participles(forms, "вня́", nil, "-", "-", "-", "вший", "вши", "в") append_imper(forms, "вними́", nil, "", "те") append_imper(forms, "вонми́", nil, "", "те") present_e_c(forms, "вни́м") present_e_c(forms, "во́нм") set_past(forms, "вня́л", nil, "", "а́", "о", "и") set_ppp_from_past_m(forms, args, data) prepend_prefix(forms, prefix) return forms end conjugations["irreg-обязывать"] = function(args, data) -- irregular, only for обязывать and обязываться local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "обя́зывать") data.title = "1a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "обя́зывать" append_participles_2stem(forms, "обя́з", nil, "обя́зыва", nil, {"ывающий", "у́ющий"}, {"ываемый", "у́емый"}, {"ывая", "у́я"}, "вший", "вши", "в") append_imper(forms, "обя́зывай", nil, "", "те") append_imper(forms, "обязу́й", nil, "", "те") present_je(forms, "обя́зыва", nil, "a") present_je(forms, "обязу́", nil, "a") set_past(forms, "обя́зывал", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end --[=[ Partial conjugation functions ]=] -- Present forms with -e-, no j-vowels. present_e_a = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у", "ешь", "ет", "ем", "ете", "ут", note) end present_e_b = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у́", "ёшь", "ёт", "ём", "ёте", "у́т", note) end present_e_c = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у́", "ешь", "ет", "ем", "ете", "ут", note) end -- Present forms with -e- and iotated stem. ABC = "a", "b" or "c", indicating -- the accent pattern. If SHCH is set, iotate final т as щ, not ч. If NOTE -- is given, add it to each form. present_je = function(forms, stem, tr, abc, shch, note) local iotated_stem, iotated_tr = com.iotation(stem, tr, shch) assert(abc == "a" or abc == "b" or abc == "c") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") -- or no_iotation local ending_1sg = hushing and (abc == "a" and "у" or "у́") or not hushing and (abc == "a" and "ю" or "ю́") if abc == "b" then append_pres_futr(forms, iotated_stem, iotated_tr, {}, "ёшь", "ёт", "ём", "ёте", (hushing and "у́т" or "ю́т"), note) else append_pres_futr(forms, iotated_stem, iotated_tr, {}, "ешь", "ет", "ем", "ете", (hushing and "ут" or "ют"), note) end append_pres_futr(forms, iotated_stem, iotated_tr, ending_1sg, {}, {}, {}, {}, {}, note) end -- Present forms with -i- (and iotated stem in the 1sg). ABC = "a", "b" or "c", -- indicating the accent pattern. If SHCH is set, iotate final т as щ, not ч. -- If NOTE is given, add it to each form. present_i = function(forms, stem, tr, abc, shch, note) local iotated_stem, iotated_tr = com.iotation(stem, tr, shch) assert(abc == "a" or abc == "b" or abc == "c") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local iotated_hushing = rfind(iotated_stem, "[шщжч]$") local hushing = rfind(stem, "[шщжч]$") local ending_1sg = iotated_hushing and (abc == "a" and "у" or "у́") or not iotated_hushing and (abc == "a" and "ю" or "ю́") if abc == "b" then append_pres_futr(forms, stem, tr, {}, "и́шь", "и́т", "и́м", "и́те", hushing and "а́т" or "я́т", note) else append_pres_futr(forms, stem, tr, {}, "ишь", "ит", "им", "ите", hushing and "ат" or "ят", note) end append_pres_futr(forms, iotated_stem, iotated_tr, ending_1sg, {}, {}, {}, {}, {}, note) end -- Add the reflexive particle to all verb forms make_reflexive = function(forms, reflex_stress) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) end if is_vowel_stem(ruentry) then forms[key] = {ruentry .. "сь" .. runotes, trentry and trentry .. "sʹ" .. trnotes} -- if a past_m form doesn't contain a stress, add a stressed -- particle "ся́" if called for elseif reflex_stress and com.is_unstressed(ruentry) and rfind(key, "^past_m") then forms[key] = {ruentry .. "ся́" .. runotes, trentry and trentry .. "sja" .. AC .. trnotes} else forms[key] = {ruentry .. "ся" .. runotes, trentry and trentry .. "sja" .. trnotes} end end end end -- Convert verb forms to pre-reform style by adding ъ to consonant-final -- forms (excluding those ending in й and ь) and converting -ий to -ій and -- -ийся to -ійся make_pre_reform = function(forms) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) if rfind(ruentry, "[бцдфгчклмнпрствшхзжщ]$") then forms[key] = {ruentry .. "ъ" .. runotes, tr} else forms[key] = {rsub(rsub(ruentry, "ий$", "ій"), "ийся$", "ійся") .. runotes, tr} end end end end local function setup_pres_futr(forms, perf, old) -- Copy the main form FROMFORM to the main form TOFORM, and copy all -- associated alternative forms. local function copy_form(fromform, toform) local fromforms = main_to_all_verb_forms[fromform] local toforms = main_to_all_verb_forms[toform] local numforms = #fromforms assert(#toforms == numforms) for i=1,numforms do forms[toforms[i]] = forms[fromforms[i]] end end -- Copy pres_futr_* to pres_* (imperfective) or futr_* (perfective). if perf then copy_form("pres_futr_1sg", "futr_1sg") copy_form("pres_futr_2sg", "futr_2sg") copy_form("pres_futr_3sg", "futr_3sg") copy_form("pres_futr_1pl", "futr_1pl") copy_form("pres_futr_2pl", "futr_2pl") copy_form("pres_futr_3pl", "futr_3pl") else copy_form("pres_futr_1sg", "pres_1sg") copy_form("pres_futr_2sg", "pres_2sg") copy_form("pres_futr_3sg", "pres_3sg") copy_form("pres_futr_1pl", "pres_1pl") copy_form("pres_futr_2pl", "pres_2pl") copy_form("pres_futr_3pl", "pres_3pl") end local futr_data = { {"futr_1sg", "бу́ду", "búdu"}, {"futr_2sg", "бу́дешь", "búdešʹ"}, {"futr_3sg", "бу́дет" .. (old and "ъ" or ""), "búdet"}, {"futr_1pl", "бу́дем" .. (old and "ъ" or ""), "búdem"}, {"futr_2pl", "бу́дете", "búdete"}, {"futr_3pl", "бу́дут" .. (old and "ъ" or ""), "búdut"} } local function insert_future(inf, inf_tr) for _, fut in ipairs(futr_data) do append_to_arg_chain(forms, fut[1], fut[1], {fut[2] .. inf, inf_tr and fut[3] .. inf_tr}) end end -- Insert future, if required (there may conceivably be multiple infitives). for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local infinitive = forms[form] if infinitive then local inf, inf_tr = extract_russian_tr(forms[form]) -- only for "бы́ть" the future forms are бу́ду, бу́дешь, etc. if inf == "бы́ть" then insert_future("", nil) elseif not perf then insert_future(" " .. inf, inf_tr and " " .. inf_tr) end end end end parse_and_stress_override = function(form, val, existing, all_existing) if rfind(form, "^pres_futr") then error("Overrides of pres_futr* are illegal, use pres_* or futr_*") end local allow_unaccented val, allow_unaccented = rsubb(val, "^%*", "") local ru, tr = nom.split_russian_tr(val) -- past_m can be unaccented in connection with reflex_stress=ся́ if not allow_unaccented and not rfind(form, "^past_m") then if tr and com.is_unstressed(ru) ~= com.is_unstressed(tr) then error("Override " .. form .. "=" .. ru .. " and translit " .. tr .. " must have same accent pattern") end if com.is_monosyllabic(ru) then ru, tr = com.make_ending_stressed(ru, tr) elseif com.needs_accents(ru) then error("Override " .. form .. "=" .. ru .. " requires an accent") end end if rfind(ru, "%+") then -- If either the existing or override has manual translit, the resulting -- form should have manual translit. We specify ALWAYS_TRANSLIT if -- the override has manual translit, so that we can substitute the -- existing translit into the override translit. local existing_ru, existing_tr = extract_russian_tr(existing, not not tr) -- used especially for present participles; substitute existing form, -- minus any "awkward-" or "none-" prefixes. ru = rsub(ru, "%+", strip_arg_status_prefix(existing_ru)) -- If there's existing translit but not in the override, make sure it's -- carried along. if existing_tr and not tr then tr = com.translit(ru) end tr = tr and rsub(tr, "%+", strip_arg_status_prefix(existing_tr)) end -- If there's an override and it doesn't match an existing form, it's -- irregular and indicate it using the IRREG marker. We don't do this if -- the override simply removes a form. We do do this if there aren't any -- existing forms, on the theory that the presence of a form when none is -- normally called for is an irregularity. When comparing against the -- existing forms, strip any status prefix (e.g. 'awkward-'). if all_existing then local all_existing_stripped = {} for _, ae in ipairs(all_existing) do local existing_ru, existing_tr = extract_russian_tr(ae) existing_ru = strip_arg_status_prefix(existing_ru) existing_tr = existing_tr and strip_arg_status_prefix(existing_tr) table.insert(all_existing_stripped, {existing_ru, existing_tr}) end if ru ~= "-" and not contains_form(all_existing_stripped, {ru, tr}) then ru = ru .. IRREG tr = tr and tr .. IRREG end end return {ru, tr} end -- Set up pres_* or futr_*; handle *sym/*tail/*tailall notes and overrides. handle_forms_and_overrides = function(args, forms, data) setup_pres_futr(forms, data.perf, data.old) local function append_value(forms, prop, value) if forms[prop] and forms[prop] ~= "" and forms[prop] ~= "-" then value = nom.split_russian_tr(value, "dopair") local curval = forms[prop] if type(curval) == "string" then curval = {curval} end forms[prop] = nom.concat_paired_russian_tr(curval, value) end end local function append_note_all(forms, proplist, value) for _, prop in ipairs(proplist) do append_value(forms, prop, value) end end local function append_note_last(forms, proplist, value, gt_one) local numprops = 0 local lastprop -- Find the last property in the series with a value for _, prop in ipairs(proplist) do if forms[prop] and forms[prop] ~= "" and forms[prop] ~= "-" then numprops = numprops + 1 lastprop = prop end end if numprops > (gt_one and 1 or 0) then append_value(forms, lastprop, value) end end for _, proplist in ipairs(all_verb_forms) do local vallist = {} -- Handle PROP_sym, which applies to all overridable properties, including -- alternative forms, and applies to exactly that property. for _, prop in ipairs(proplist) do if args[prop .. "_sym"] then append_value(forms, prop, args[prop .. "_sym"]) end end local propname = proplist[1] -- Handle PROP_tail, which applies to a series of properties (e.g. past_m, -- past_m2, ...) and appends to the last one. if args[propname .. "_tail"] then append_note_last(forms, proplist, args[propname .. "_tail"]) end -- Handle PROP_tailall, which applies to a series of properties and -- appends to all. if args[propname .. "_tailall"] then append_note_all(forms, proplist, args[propname .. "_tailall"]) end end -- Now handle pasttail, pasttailall, prestail, prestailall, etc. -- Table listing tail-arg prefix and corresponding verb forms. local tailargs = { {"past", past_verb_forms}, {"pres", pres_verb_forms}, {"futr", futr_verb_forms}, {"impr", impr_verb_forms}, {"part", part_verb_forms}, {"prespart", pres_part_verb_forms}, {"pastpart", past_part_verb_forms}, {"", all_main_verb_forms} } for _, tailspec in ipairs(tailargs) do tailforms = tailspec[2] -- Handle the ...tail variants. tailarg = tailspec[1] .. "tail" if args[tailarg] then track(tailarg) for _, prop in ipairs(tailforms) do append_note_last(forms, main_to_all_verb_forms[prop], args[tailarg], ">1") end end -- Handle the ...tailall variants. tailallarg = tailspec[1] .. "tailall" if args[tailallarg] then track(tailallarg) for _, prop in ipairs(tailforms) do append_note_all(forms, main_to_all_verb_forms[prop], args[tailallarg]) end end end --handle overrides (formerly we only had past_pasv_part as a --general override, plus scattered main-form overrides in particular --conjugation classes) for _, all_forms in pairs(main_to_all_verb_forms) do local i = 0 local orig_forms = {} for _, form in ipairs(all_forms) do if forms[form] then table.insert(orig_forms, forms[form]) end end for _, form in ipairs(all_forms) do i = i + 1 -- If we auto-generated the past passive participle in order to -- check for irregular overrides, make sure to erase any such -- participles that weren't overridden. This happens for example -- in обнять, where there are two automatically generated past -- passive participles but a single ppp=о́внятый override. local override = args[form] or ( data.ppp_auto_generated and rfind(form, "^past_pasv_part") and "-" ) if override then forms[form] = parse_and_stress_override(form, override, forms[form], orig_forms) elseif i == 1 then forms[form] = forms[form] or "" end end end end -- Finish generating the forms; primarily, clear out unused forms. finish_generating_forms = function(forms, data) -- Convert any main form that's nil (meaning no forms at all corresponding -- to this main form) to the empty string. for main_form, _ in pairs(main_to_all_verb_forms) do if not forms[main_form] then forms[main_form] = "" end end -- Set the main form FORM to the empty string, and corresponding alt forms -- to nil. local function clear_form(form) local i = 0 for _, altform in ipairs(main_to_all_verb_forms[form]) do i = i + 1 if i == 1 then forms[altform] = "" else forms[altform] = nil end end end -- Intransitive and reflexive verbs have no passive participles -- (unless has_prpp=y and/or has_ppp=y). if data.intr or data.refl then if not data.has_prpp then clear_form("pres_pasv_part") end if not data.has_ppp then clear_form("past_pasv_part") end end if data.refl then -- no past_adv_part_short for reflexive verbs clear_form("past_adv_part_short") end -- Impersonal verbs normally have no passive participles, but allow them -- if there's specifically an override. We only do this for the present -- passive participle because the past passive participle isn't inserted -- by default, and we still want +p to work, which doesn't currently set -- data.ppp_override. if data.impers and not data.prpp_override then clear_form("pres_pasv_part") end if data.impers then clear_form("pres_1sg") clear_form("pres_2sg") clear_form("pres_1pl") clear_form("pres_2pl") clear_form("pres_3pl") clear_form("futr_1sg") clear_form("futr_2sg") clear_form("futr_1pl") clear_form("futr_2pl") clear_form("futr_3pl") clear_form("past_m") clear_form("past_f") clear_form("past_pl") clear_form("past_m_short") clear_form("past_f_short") clear_form("past_pl_short") clear_form("pres_actv_part") clear_form("past_actv_part") clear_form("pres_adv_part") clear_form("past_adv_part") clear_form("past_adv_part_short") clear_form("impr_sg") clear_form("impr_pl") end -- Perfective and iterative verbs have no present forms, as well as -- verbs marked nopres=1. if data.perf or data.iter or data.nopres then clear_form("pres_actv_part") clear_form("pres_pasv_part") clear_form("pres_adv_part") clear_form("pres_1sg") clear_form("pres_2sg") clear_form("pres_3sg") clear_form("pres_1pl") clear_form("pres_2pl") clear_form("pres_3pl") end -- Some verbs (e.g. грясти́, густи́) have no past if data.nopast then clear_form("past_m") clear_form("past_f") clear_form("past_n") clear_form("past_pl") clear_form("past_m_short") clear_form("past_f_short") clear_form("past_n_short") clear_form("past_pl_short") clear_form("past_actv_part") clear_form("past_pasv_part") clear_form("past_adv_part") clear_form("past_adv_part_short") end -- Iterative verbs and verbs marked noimpr=1 have no imperative forms. if data.iter or data.noimpr then clear_form("impr_sg") clear_form("impr_pl") end -- Iterative verbs and verbs marked nofutr=1 have no future forms. if data.iter or data.nofutr then clear_form("futr_1sg") clear_form("futr_2sg") clear_form("futr_3sg") clear_form("futr_1pl") clear_form("futr_2pl") clear_form("futr_3pl") end --handle "none-" and "awkward-" prefixes (used especially for pres_pasv_part) local footnote_sym = nil for _, all_forms in pairs(main_to_all_verb_forms) do local i = 0 for _, form in ipairs(all_forms) do i = i + 1 if forms[form] then local formru, formtr = extract_russian_tr(forms[form]) if rfind(formru, "^none%-") then if i == 1 then forms[form] = "" else forms[form] = nil end elseif rfind(formru, "^awkward%-") then if not footnote_sym then footnote_sym = next_note_symbol(data) ut.insert_if_not(data.internal_notes, footnote_sym .. " Rare and awkward.") end forms[form] = {rsub(formru, "^awkward%-", "") .. footnote_sym, formtr and rsub(formtr, "^awkward%-", "") .. footnote_sym} end end end end --Insert footnote for IRREG symbol if present. for _, all_forms in pairs(main_to_all_verb_forms) do for _, form in ipairs(all_forms) do if forms[form] then local formru, formtr = extract_russian_tr(forms[form]) if rfind(formru, IRREG) then ut.insert_if_not(data.internal_notes, IRREG .. " Irregular.") end end end end end local accel_forms = { -- present tense pres_1sg = "1|s|pres|ind", pres_2sg = "2|s|pres|ind", pres_3sg = "3|s|pres|ind", pres_1pl = "1|p|pres|ind", pres_2pl = "2|p|pres|ind", pres_3pl = "3|p|pres|ind", -- future tense futr_1sg = "1|s|fut|ind", futr_2sg = "2|s|fut|ind", futr_3sg = "3|s|fut|ind", futr_1pl = "1|p|fut|ind", futr_2pl = "2|p|fut|ind", futr_3pl = "3|p|fut|ind", -- imperative impr_sg = "2|s|imp", impr_pl = "2|p|imp", -- past past_m = "m|s|past|ind", past_f = "f|s|past|ind", past_n = "n|s|past|ind", past_pl = "p|past|ind", past_m_short = "short|m|s|past|ind", past_f_short = "short|f|s|past|ind", past_n_short = "short|n|s|past|ind", past_pl_short = "short|p|past|ind", -- active participles pres_actv_part = "pres|act|part", past_actv_part = "past|act|part", -- passive participles pres_pasv_part = "pres|pass|part", past_pasv_part = "past|pass|part", -- adverbial participles pres_adv_part = "pres|adv|part", past_adv_part = "past|adv|part", past_adv_part_short = "short|past|adv|part", -- infinitive infinitive = "inf", } -- Make the table make_table = function(forms, title, perf, intr, impers, notes, internal_notes, old) local infinitives = {} for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local infinitive = forms[form] if infinitive then local inf, inf_tr = extract_russian_tr(forms[form]) if inf ~= "-" then ut.insert_if_not(infinitives, inf) end end end -- Group forms together for a given key and combine adjacent forms with the same -- Russian (they should always have different translits). Take care not to introduce -- manual translit unnecessarily. local grouped_forms = {} for dispform, sourceforms in pairs(disp_verb_form_map) do local entry = {} for _, form in ipairs(sourceforms) do local ru, tr = extract_russian_tr(forms[form]) -- check for empty strings, dashes and nil's if ru and ru ~= "" and ru ~= "-" and ru ~= "&mdash;" then if #entry > 0 then local lastru, lasttr = extract_russian_tr(entry[#entry]) if lastru == ru then if not lasttr and not tr or lasttr == tr then error("Russian form " .. ru .. " is duplicated, probably due to a duplicative override") end lasttr = lasttr or com.translit(lastru) tr = tr or com.translit(ru) entry[#entry] = {ru, lasttr .. " ''or'' " .. tr} else table.insert(entry, {ru, tr}) end else table.insert(entry, {ru, tr}) end end end grouped_forms[dispform] = entry end local title = (old and "Pre-reform conjugation" or "Conjugation") .. (#infinitives == 0 and "" or " of <span lang=\"ru\" class=\"Cyrl\">''" .. table.concat(infinitives, ", ") .. "''</span>") .. (title and " (" .. title .. ")" or "") local function add_links(ru, rusuf, runotes, tr, trnotes, accel) local ruspan if old then ruspan = m_links.full_link({lang = lang, term = com.remove_jo(ru), accel = accel, alt = not ru:find("[[", 1, true) and ru, tr = "-"}) else ruspan = m_links.full_link({lang = lang, term = ru, accel = accel, tr = "-"}) end if rusuf ~= "" then rusuf = "<span lang=\"ru\" class=\"Cyrl\">" .. rusuf .. "</span>" end return ruspan .. rusuf .. runotes .. "<br/>" .. require("Module:script utilities").tag_translit(tr .. trnotes, lang, "default", 'style="color: #888"') end -- NOTE: No need to check for multiple infinitives because the accel system -- doesn't support multiple lemmas. local lemma, lemmatr = extract_russian_tr(forms["infinitive"]) -- check for empty strings, dashes and nil's if lemma and lemma ~= "" and lemma ~= "-" and lemma ~= "&mdash;" then lemma, _ = m_table_tools.separate_notes(lemma) if lemmatr then lemmatr, _ = m_table_tools.separate_notes(lemmatr) end else -- In case the lemma is an empty string or dash, set to nil so we don't -- set a lemma in the accelerator and fall back to the page name. lemma = nil lemmatr = nil end -- Convert to displayed form local disp = {} for key, entry in pairs(grouped_forms) do for i, form in ipairs(entry) do local ru, origtr = extract_russian_tr(form) local tr = origtr or ru and com.translit(ru) local ruentry, runotes = m_table_tools.get_notes(ru) local trentry, trnotes = m_table_tools.get_notes(tr) local accel_form = accel_forms[key] if not accel_form then error("Unrecognized key " .. key .. " when looking up accelerator form") end local accel if origtr and origtr:find(" ''or'' ") then -- Multiple translits for a given Russian term. -- FIXME! Support this. accel = nil else accel = { form = accel_form, translit = origtr, lemma = lemma, lemma_translit = lemmatr} end if rfind(key, "^futr") then -- Add link to first word (form of 'to be') tobe, inf = rmatch(ruentry, "^([^ ]*) ([^ ]*)$") if tobe then -- No accelerators for imperfective future, as it's just the future of "to be" -- plus the infinitive. entry[i] = add_links(tobe, " " .. inf, runotes, trentry, trnotes, nil) else entry[i] = add_links(ruentry, "", runotes, trentry, trnotes, accel) end else entry[i] = add_links(ruentry, "", runotes, trentry, trnotes, accel) end end disp[key] = table.concat(entry, ",<br/>") if disp[key] == "" then disp[key] = "&mdash;" end end local all_notes = {} for _, note in ipairs(internal_notes) do local symbol, entry = m_table_tools.get_initial_notes(note) table.insert(all_notes, symbol .. entry) end for _, note in ipairs(notes) do local symbol, entry = m_table_tools.get_initial_notes(note) table.insert(all_notes, symbol .. entry) end local notes_text table.insert(all_notes, 1, "Note: For declension of participles, see their entries. Adverbial participles are indeclinable.") notes_text = table.concat(all_notes, "<br />") .. "\n" return require("Module:TemplateStyles")("Module:ru-verb/style.css") .. [=[<div class="NavFrame" style="width:49.6em;"> <div class="NavHead" style="text-align:left; background:#e0e0ff;">]=] .. title .. [=[</div> <div class="NavContent"> {| class="inflection inflection-ru inflection-verb inflection-table" |+ ]=] .. notes_text .. [=[ |- class="rowgroup" ! colspan="3" | ]=] .. (perf and [=[[[совершенный вид|perfective aspect]]]=] or [=[[[несовершенный вид|imperfective aspect]]]=]) .. [=[ |- ! [[неопределённая форма|infinitive]] | colspan="2" | ]=] .. disp.infinitive .. [=[ |- class="rowgroup" ! style="width:15em" | [[причастие|participles]] ! [[настоящее время|present tense]] ! [[прошедшее время|past tense]] |- ! [[действительный залог|active]] | ]=] .. disp.pres_actv_part .. [=[ || ]=] .. disp.past_actv_part .. [=[ |- ! [[страдательный залог|passive]] | ]=] .. disp.pres_pasv_part .. [=[ || ]=] .. disp.past_pasv_part .. [=[ |- ! [[деепричастие|adverbial]] | ]=] .. disp.pres_adv_part .. [=[ || ]=] .. disp.past_adv_part .. [=[ |- class="rowgroup" ! ! [[настоящее время|present tense]] ! [[будущее время|future tense]] |- ! [[первое лицо|1st]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">я</span>) | ]=] .. disp.pres_1sg .. [=[ || ]=] .. disp.futr_1sg .. [=[ |- ! [[второе лицо|2nd]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">ты</span>) | ]=] .. disp.pres_2sg .. [=[ || ]=] .. disp.futr_2sg .. [=[ |- ! [[третье лицо|3rd]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">он/она́/оно́</span>) | ]=] .. disp.pres_3sg .. [=[ || ]=] .. disp.futr_3sg .. [=[ |- ! [[первое лицо|1st]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">мы</span>) | ]=] .. disp.pres_1pl .. [=[ || ]=] .. disp.futr_1pl .. [=[ |- ! [[второе лицо|2nd]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">вы</span>) | ]=] .. disp.pres_2pl .. [=[ || ]=] .. disp.futr_2pl .. [=[ |- ! [[третье лицо|3rd]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">они́</span>) | ]=] .. disp.pres_3pl .. [=[ || ]=] .. disp.futr_3pl .. [=[ |- class="rowgroup" ! [[повелительное наклонение|imperative]] ! [[единственное число|singular]] ! [[множественное число|plural]] |- ! | ]=] .. disp.impr_sg .. [=[ || ]=] .. disp.impr_pl .. [=[ |- class="rowgroup" ! [[прошедшее время|past tense]] ! [[единственное число|singular]] ! [[множественное число|plural]]<br/>(<span lang="ru" class="Cyrl">мы/вы/они́</span>) |- ! [[мужской род|masculine]] (<span lang="ru" class="Cyrl">я/ты/он</span>) | ]=] .. disp.past_m .. [=[ || rowspan="3" | ]=] .. disp.past_pl .. [=[ |- ! [[женский род|feminine]] (<span lang="ru" class="Cyrl">я/ты/она́</span>) | ]=] .. disp.past_f .. [=[ |- ! style="background-color: #ffffe0;" | [[средний род|neuter]] (<span lang="ru" class="Cyrl">оно́</span>) | ]=] .. disp.past_n .. [=[ |} </div> </div>]=] end return export -- For Vim, so we get 4-space tabs -- vim: set ts=4 sw=4 noet: ptwcky15mzc4m5e6h6mjj09guntacnb 5672502 5672500 2026-06-29T15:19:40Z MustafaCavlak 59368 5672502 Scribunto text/plain --[=[ This module contains functions for creating inflection tables for Russian verbs. Author: Benwing, rewritten from early version by Atitarev, earliest version by CodeCat NOTE: This module is partly converted to support manual translit, in the form CYRILLIC//LATIN (i.e. with a // separating the Cyrillic and Latin parts). All the general infrastructure supports manual translit; the only thing that doesn't is some of the specific verb conjugation functions. In particular, all of the class 1, 2, 3 and 4 conjugation functions support manual translit, and the rest don't. To convert another, follow the model of one of the already-converted functions. Note that an individual form (an entry in the 'forms' table) can be either a string (no special manual translit; generally this originates from the portion of the code that doesn't support manual translit), or a one-element list {CYRILLIC} (no special manual translit), or a two-element list {CYRILLIC, LATIN} with manual translit specified. The code is careful only to generate manual translit when it's needed, to avoid penalizing the majority of cases where manual transit isn't needed. ]=] local m_utilities = require("Modül:araçlar") local ut = require("Module:utils") local m_links = require("Modül:bağlantılar") local com = require("Modül:ru-genel") local nom = require("Modül:ru-nominal") local m_debug = require("Modül:debug") local m_table_tools = require("Modül:table tools") -- If enabled, compare this module with new version of module to make -- sure all conjugations are the same. local test_new_ru_verb_module = false local export = {} -- Within this module, conjugations are the functions that do the actual -- conjugating by creating the forms of a basic verb. -- They are defined further down. local conjugations = {} local lang = require("Modül:diller").getirKodaGore("ru") local u = mw.ustring.char local rfind = mw.ustring.find local rsubn = mw.ustring.gsub local rmatch = mw.ustring.match local rsplit = mw.text.split local usub = mw.ustring.sub local AC = u(0x0301) -- acute = ́ local DIA = u(0x0308) -- diaeresis = ̈ local PSEUDOCONS = u(0xFFF2) -- pseudoconsonant placeholder, matching ru-common local IRREG = "△" -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end -- version of rsubn() that returns a 2nd argument boolean indicating whether -- a substitution was made. local function rsubb(term, foo, bar) local retval, nsubs = rsubn(term, foo, bar) return retval, nsubs > 0 end -- Fancy version of ine() (if-not-empty). Converts empty string to nil, -- but also strips leading/trailing space and then single or double quotes, -- to allow for embedded spaces. local function ine(arg) if not arg then return nil end arg = rsub(arg, "^%s*(.-)%s*$", "%1") if arg == "" then return nil end local inside_quotes = rmatch(arg, '^"(.*)"$') if inside_quotes then return inside_quotes end inside_quotes = rmatch(arg, "^'(.*)'$") if inside_quotes then return inside_quotes end return arg end local function is_vowel_stem(stem) return rfind(stem, "[" .. com.vowel .. AC .. DIA .. "]$") end -- Return the next number to use as an internal note symbol, starting at 1. -- We look at existing internal notes to see if the symbol is already used. local function next_note_symbol(data) local nextsym = 1 while true do local sym_already_seen = false for _, note in ipairs(data.internal_notes) do if rfind(note, "^" .. nextsym .. " ") then sym_already_seen = true break end end if sym_already_seen then nextsym = nextsym + 1 else break end end return nextsym end -- FIXME: Move to utils -- Iterate over a chain of parameters, FIRST then PREF2, PREF3, ..., -- inserting into LIST (newly created if omitted). Return LIST. local function get_arg_chain(args, first, pref, list) if not list then list = {} end local val = args[first] local i = 2 while val do table.insert(list, val) val = args[pref .. i] i = i + 1 end return list end -- FIXME: Move to utils -- Set a chain of parameters, FIRST then PREF2, PREF3, ..., from LIST. local function set_arg_chain(args, first, pref, list) local param = first local i = 2 for _, val in ipairs(list) do args[param] = val param = pref .. i i = i + 1 end end -- For a given form in a conjugation table, we allow either strings or -- two-element lists {RUSSIAN, TRANSLIT}, where TRANSLIT can be nil -- (equivalent to a one-element list). When comparing them, we have to take -- this into account. local function forms_equal(form1, form2) if type(form1) ~= "table" then form1 = {form1} end if type(form2) ~= "table" then form2 = {form2} end return ut.equals(form1, form2) end local function contains_form(forms, form) for _, f in ipairs(forms) do if forms_equal(f, form) then return true end end return false end -- FIXME: Move to utils -- Append to the end of a chain of parameters, FIRST then PREF2, PREF3, ..., -- if the value isn't already present. local function append_to_arg_chain(args, first, pref, newval) local nextarg = first local i = 2 if newval == "" then error("Internal error: attempt to insert blank value into arg chain") end while true do if not args[nextarg] then break end if forms_equal(args[nextarg], newval) then return nil end nextarg = pref .. i i = i + 1 end args[nextarg] = newval return nextarg end local function get_true_arg(arg, not_off_by_1) -- We normally move all params down by one because the first param is the -- verb type; so reflect this correctly if the arg is numeric and -- not_off_by_1 isn't given return (not_off_by_1 or type(arg) ~= "number") and arg or arg + 1 end local function getarg(args, arg, default, paramdesc, not_off_by_1) paramdesc = paramdesc or "Parameter " .. get_true_arg(arg, not_off_by_1) default = default or "-" --PAGENAME = mw.loadData("Modül:başlık başı/veri").pagename local NAMESPACE = mw.title.getCurrentTitle().nsText return args[arg] or (NAMESPACE == "Template" and default) or error(paramdesc .. " has not been provided") end local function check_stressed_arg(val, arg) -- don't consider suffixes if not rfind(val, "^%-") and not com.is_nonsyllabic(val) and not com.is_stressed(val) then error("Argument value " .. val .. " (parameter " .. get_true_arg(arg) .. ") must be stressed") end return val end local function get_stressed_arg(args, arg, default, paramdesc) local retval = getarg(args, arg, default, paramdesc) check_stressed_arg(retval, arg) return retval end local function get_opt_stressed_arg(args, arg) return args[arg] and get_stressed_arg(args, arg) or nil end local function check_unstressed_arg(val, arg) if com.is_stressed(val) then error("Argument value " .. val .. " (parameter " .. get_true_arg(arg) .. ") should not be stressed") end return val end local function get_unstressed_arg(args, arg, default, paramdesc) local retval = getarg(args, arg, default, paramdesc) check_unstressed_arg(retval, arg) return retval end local function get_opt_unstressed_arg(args, arg) return args[arg] and get_unstressed_arg(args, arg) or nil end local function no_stray_args(args, maxarg) for i=(maxarg + 1), 20 do if args[i] then error("Value for argument " .. get_true_arg(i) .. " not allowed (" .. args[i] .. " supplied)") end end end -- Extract a form spec (either a single string or a two-element table {RU, TR} -- into the component Russian and transliterated components. Normally, if -- an explicit manual translit wasn't given, the resulting translit will be -- nil; but if ALWAYS_TRANSLIT is given, it will be auto-transliterated from -- the Russian as needed. local function extract_russian_tr(form, always_translit) local ru, tr if type(form) == "table" then ru, tr = form[1], form[2] else ru = form end if not tr and always_translit then tr = ru and com.translit(ru) end return ru, tr end local function strip_arg_status_prefix(arg) if not arg then return arg, "" end local subbed arg, subbed = rsubb(arg, "^awkward%-", "") if subbed then return arg, "awkward-" end arg, subbed = rsubb(arg, "^none%-", "") if subbed then return arg, "none-" end return arg, "" end local function track(page) m_debug.track("ru-verb/" .. page) return true end -- Forward functions local present_e_a local present_e_b local present_e_c local present_je local present_i local make_reflexive local make_pre_reform local parse_and_stress_override local handle_forms_and_overrides local finish_generating_forms local make_table local all_verb_types = { "pf", "pf-intr", "pf-refl", "pf-impers", "pf-intr-impers", "pf-refl-impers", "impf", "impf-intr", "impf-refl", "impf-impers", "impf-intr-impers", "impf-refl-impers"} -- Examples of alternatives in use: -- past_m2: со́здал/созда́л, пе́редал/переда́л, о́тдал/отда́л, при́нялся/принялся́ -- past_m3: for verbs with three past masculine sg forms: за́нялся, заня́лся, занялс́я (заня́ться) -- past_n2: да́ло, дал́о; вз́яло, взяло́ -- past_pl2: разобрали́сь (разобрали́) -- past_m_short: short forms in 3a (исчез, сох, etc.) -- past_f_short: short forms in 3a (исчезла, сохла, etc.) -- past_n_short: short forms in 3a (исчезло, сохло, etc.) -- past_pl_short: short forms in 3a (исчезли, сохли, etc.) -- past_adv_parts: -- тереть: тере́вши, тёрши, short: тере́в -- умереть: умере́вши, у́мерши, short: умере́в -- pres_adv_part: сыпля, сыпя, лёжа (лежать) -- pres_2sg2: сыплешь, сыпешь -- pres_3sg2: сыплет, сыпет -- pres_1pl2: сыплем, сыпем -- pres_2pl2: сыплете, сыпете -- pres_3pl2: сыплют, сыпют -- futr_2sg2: насыплешь, насыпешь -- futr_3sg2: насыплет, насыпет -- futr_1pl2: насыплем, насыпем -- futr_2pl2: насыплете, насыпете -- futr_3pl2: насыплют, насыпют -- List of all main verb forms. Short forms (those ending in "_short") -- must be listed after the corresponding non-short forms. local all_main_verb_forms = { -- present tense "pres_1sg", "pres_2sg", "pres_3sg", "pres_1pl", "pres_2pl", "pres_3pl", -- future tense "futr_1sg", "futr_2sg", "futr_3sg", "futr_1pl", "futr_2pl", "futr_3pl", -- present-future tense. The conjugation functions generate the -- "present-future" tense instead of either the present or future tense, -- since the same forms are used in the present imperfect and future -- perfect. These forms are later copied into the present or future in -- finish_generating_forms(). "pres_futr_1sg", "pres_futr_2sg", "pres_futr_3sg", "pres_futr_1pl", "pres_futr_2pl", "pres_futr_3pl", -- imperative "impr_sg", "impr_pl", -- past "past_m", "past_f", "past_n", "past_pl", "past_m_short", "past_f_short", "past_n_short", "past_pl_short", -- active participles "pres_actv_part", "past_actv_part", -- passive participles "pres_pasv_part", "past_pasv_part", -- adverbial participles "pres_adv_part", "past_adv_part", "past_adv_part_short", -- infinitive "infinitive" } -- List of all verb forms. Each element is a list, where the first element -- is the "main" form and the remainder are alternatives. The following -- *MUST* hold: -- 1. Forms must be given in the order they will appear in the outputted -- table. -- 2. Short forms (those ending in "_short") must be listed after the -- corresponding non-short forms. -- 3. For each person, e.g. '2sg', there must be the same number of -- futr_PERSON, pres_PERSON and pres_futr_PERSON forms, and the alternative -- forms must be listed in the same order. -- -- FIXME!!! We should fix things so we no longer need to compute this table. local all_verb_forms = {} -- Compile all_verb_forms for _, mainform in ipairs(all_main_verb_forms) do local entry = {} table.insert(entry, mainform) for i=2,9 do table.insert(entry, mainform .. i) end table.insert(all_verb_forms, entry) end local prop_aliases = { pap="past_actv_part", paptail="past_actv_part_tail", paptailall="past_actv_part_tailall", ppp="past_pasv_part", ppptail="past_pasv_part_tail", ppptailall="past_pasv_part_tailall", prap="pres_actv_part", praptail="pres_actv_part_tail", praptailall="pres_actv_part_tailall", prpp="pres_pasv_part", prpptail="pres_pasv_part_tail", prpptailall="pres_pasv_part_tailall", padp="past_adv_part", padptail="past_adv_part_tail", padptailall="past_adv_part_tailall", padp_short="past_adv_part_short", padp_shorttail="past_adv_part_short_tail", padp_shorttailall="past_adv_part_short_tailall", pradp="pres_adv_part", pradptail="pres_adv_part_tail", pradptailall="pres_adv_part_tailall", } -- Table mapping "main" to the list of all forms in the series (e.g. -- past_m, past_m2, past_m3, etc.). If a main form (e.g. past_m) is missing, -- it needs to end up with a value of "", whereas the alternatives -- (e.g. past_m2, past_m3) need to end up with a value of nil. local main_to_all_verb_forms = {} -- List of the main verb forms for the past. local past_verb_forms = {"past_m", "past_f", "past_n", "past_pl"} -- List of the main verb forms for the present. local pres_verb_forms = {"pres_1sg", "pres_2sg", "pres_3sg", "pres_1pl", "pres_2pl", "pres_3pl"} -- List of the main verb forms for the future. local futr_verb_forms = {"futr_1sg", "futr_2sg", "futr_3sg", "futr_1pl", "futr_2pl", "futr_3pl"} -- List of the main verb forms for the imperative. local impr_verb_forms = {"impr_sg", "impr_pl"} -- List of the main verb forms for participles. local part_verb_forms = {"pres_actv_part", "past_actv_part", "pres_pasv_part", "past_pasv_part", "pres_adv_part", "past_adv_part", "past_adv_part_short"} -- List of the main verb forms for present participles. local pres_part_verb_forms = {"pres_actv_part", "pres_pasv_part", "pres_adv_part"} -- List of the main verb forms for past participles. local past_part_verb_forms = {"past_actv_part", "past_pasv_part", "past_adv_part", "past_adv_part_short"} -- Compile main_to_all_verb_forms. for _, proplist in ipairs(all_verb_forms) do main_to_all_verb_forms[proplist[1]] = proplist end -- Map listing the forms to be displayed, and the verb forms used to generate -- the displayed form, in order. For example, under past_m will be found -- {"past_m_short", "past_m", "past_m2", "past_m3"} because those forms in -- that order are displayed in the table under "masculine singular past". local disp_verb_form_map = {} for _, proplist in ipairs(all_verb_forms) do local key = proplist[1] -- if we find short forms, insert them at the beginning of the list for -- the corresponding full forms. This requires that short forms are -- listed in all_verb_forms after the corresponding full forms. if rfind(key, "_short$") then local full_key = rsub(key, "_short$", "") -- short forms should occur in list after full forms assert(#(disp_verb_form_map[full_key]) > 0) -- build entry for full form, consisting first of the short forms, -- in order, then the full forms, in order. local new_entry = {} for _, form in ipairs(proplist) do table.insert(new_entry, form) end for _, form in ipairs(disp_verb_form_map[full_key]) do table.insert(new_entry, form) end disp_verb_form_map[full_key] = new_entry elseif rfind(key, "^pres_futr") then -- skip these forms, not displayed else disp_verb_form_map[key] = mw.clone(proplist) end end local all_verb_props = mw.clone(all_verb_forms) local non_form_props = {"title", "perf", "intr", "impers", "categories", "notes", "internal_notes"} for _, prop in ipairs(non_form_props) do table.insert(all_verb_props, {prop}) end -- Clone parent's args while also assigning nil to empty strings and splitting -- arg sets (numeric args separated by "or"), assigning named args to -- all all sets. Handle aliases in the process. Extract conjugation type -- from the first arg of the arg set (for the initial arg set, this will be -- arg 2 because arg 1 is the verb type), assigning to '.conj_type' of the -- arg set. Return arg sets. local function split_args_handle_aliases(frame) local args = frame:getParent().args local arg_sets = {} local arg_set = {} -- Verb type, e.g. impf, pf, impf-intr, pf-intr, impf-refl, pf-refl, etc. -- Default to impf on the template page so that there is no script error. local verb_type = getarg(args, 1, "impf", "Verb type (first parameter)") local offset = 1 -- Find maximum-numbered arg, allowing for holes. local max_arg = 1 -- needs to be 1 not 0 so template pages display ok for pname, param in pairs(args) do if type(pname) == "number" and pname > max_arg then max_arg = pname end end -- Now gather the numbered arguments. for i=2,(max_arg + 1) do local end_arg_set = false if i == max_arg + 1 or args[i] == "or" then end_arg_set = true end if end_arg_set then table.insert(arg_sets, arg_set) arg_set = {} offset = i else arg_set[i - offset] = ine(args[i]) end end -- Insert named arguments into all arg sets, mapping aliases appropriately. for pname, param in pairs(args) do if type(pname) == "string" then local argval = ine(param) local mainprop, num = rmatch(pname, "^([a-z_]+)([0-9]*)$") for i=1,#arg_sets do if not mainprop then arg_sets[i][pname] = argval else mainprop = prop_aliases[mainprop] or mainprop arg_sets[i][mainprop .. num] = argval end end end end -- If we're conjugating a suffix, insert a pseudoconsonant at the beginning -- of all forms, so they get conjugated as if ending in a consonant. -- We remove the pseudoconsonant later. for i=1,#arg_sets do asif_prefix = (arg_sets[i]["asif_prefix"] or arg_sets[i][2] and rfind(arg_sets[i][2], "^%-") and PSEUDOCONS) if asif_prefix then for k, v in pairs(arg_sets[i]) do arg_sets[i][k] = rsub(v, "^%-", "-" .. asif_prefix) end end end -- Frob conjugation type. for i=1,#arg_sets do local arg1 = arg_sets[i][1] local conj_type if arg1 then local orig_arg1 = arg1 -- This complex spec matches matches 3°a, 3oa, 4a1a, 6c1a, -- 1a6a, 6a1as13, 6a1as14, 11*b, etc. conj_type = rmatch(arg1, "^([0-9]+[*°o0-9abc]*[abc]s?1?[34]?)") arg1 = rsub(arg1, "^[0-9]+[*°o0-9abc]*[abc]s?1?[34]?", "") if not conj_type then if rfind(arg1, "^irreg") then conj_type = "irreg" arg1 = rsub(arg1, "^irreg", "") end if not conj_type then -- Check for Cyrillic, a common mistake (esp. Cyrillic а) if rfind(orig_arg1, "[абцдеѣфгчийклмнопярстувшхызёюжэщьъ]") then error("Unrecognized conjugation type (WARNING, has Cyrillic in it): " .. orig_arg1) else error("Unrecognized conjugation type: " .. orig_arg1) end end end -- The * variant is conventionally written e.g. 11*b; if found in -- the conj_type, move it to the beginning of the remainder if rfind(conj_type, "%*") then conj_type = rsub(conj_type, "%*", "") arg1 = "*" .. arg1 end arg_sets[i][1] = arg1 else local NAMESPACE = mw.title.getCurrentTitle().nsText if NAMESPACE == "Template" and i == 1 then conj_type = "1a" else error("Must specify argument 2 (conjugation type)") end end arg_sets[i]["conj_type"] = conj_type end return arg_sets, verb_type end function export.do_generate_forms(arg_sets, verb_type, old) local set1 = arg_sets[1] local notes = get_arg_chain(set1, "notes", "notes") local forms = {} local categories = {} if not ut.contains(all_verb_types, verb_type) then error("Invalid verb type " .. verb_type) end local data = {} data.verb_type = verb_type --impersonal data.impers = rfind(verb_type, "impers") data.intr = rfind(verb_type, "intr") data.perf = rfind(verb_type, "^pf") data.iter = set1["iter"] data.nopres = set1["nopres"] data.nopast = set1["nopast"] data.nofutr = set1["nofutr"] data.noimpr = set1["noimpr"] if data.iter and data.perf then error("Iterative verbs must be imperfective") end data.old = old data.has_ppp = set1["has_ppp"] data.has_prpp = set1["has_prpp"] data.ppp_override = false data.prpp_override = false for _, form in ipairs(main_to_all_verb_forms["past_pasv_part"]) do if set1[form] then data.ppp_override = true break end end data.main_ppp_override = not not set1["past_pasv_part"] for _, form in ipairs(main_to_all_verb_forms["pres_pasv_part"]) do if set1[form] then data.prpp_override = true break end end data.internal_notes = {} local titles = {} for i=1,#arg_sets do local args = arg_sets[i] local conj_type = args.conj_type -- Support e.g. 3oa in place of 3°a conj_type = rsub(conj_type, "o", "°") track("conj-" .. conj_type) -- FIXME, convert to regular category track("conj-" .. conj_type .. "/" .. verb_type) -- FIXME, convert to regular category data.conj_type = conj_type data.cat_conj_types = {conj_type} if conj_type == "irreg" then data.title = "irregular" else data.title = conj_type end if not conjugations[conj_type] then error("Unknown conjugation type '" .. conj_type .. "'") end if args[2] then local inf, tr = nom.split_russian_tr(args[2]) if rfind(inf, "[тч]ься$") then inf = rsub(inf, "ся$", "") tr = nom.strip_tr_ending(tr, "ся") data.refl = true elseif rfind(inf, "ти́?сь$") then -- 7a (вы́вестись), 7b (вести́сь) or derivative of -йти́ (разойти́сь) inf = rsub(inf, "сь$", "") tr = nom.strip_tr_ending(tr, "сь") data.refl = true elseif rfind(inf, "[тч]ь$") then -- Allow monosyllabic infinitives to be specified without stress if com.is_monosyllabic(inf) and not rfind(inf, "^%-") then inf, tr = com.make_ending_stressed(inf, tr) end end if tr then args[2] = inf .. "//" .. tr else args[2] = inf end end if data.refl and data.intr then error("Can't specify -intr with reflexive verbs") end if data.has_ppp or data.has_prpp then if data.refl then error("Can't specify has_ppp=y or has_prpp=y with reflexive verbs") end if not data.intr then error("Can only specify has_ppp=y or has_prpp=y with intransitive verbs") end end data.shouldnt_have_ppp = data.refl or not data.has_ppp and data.intr data.shouldnt_have_prpp = data.refl or not data.has_prpp and data.intr if data.ppp_override and data.shouldnt_have_ppp then error("Shouldn't specify past passive participle with reflexive or intransitive verbs, if it's needed use has_ppp=y") elseif data.perf and not data.shouldnt_have_ppp and not data.ppp_override then -- possible omissions track("perfective-no-ppp") end if data.prpp_override and data.shouldnt_have_prpp then error("Shouldn't specify present passive participle with reflexive or intransitive verbs, if it's needed use has_prpp=y") end -- Call conjugation function. It will return a table of forms -- as if it's the first arg set. If it is in fact the first -- arg set, we just use the table directly (we may destructively -- modify it if there are later arg sets, but this is OK because -- no one else but us uses the table). Otherwise we need to -- append the values from the table to those of the previous -- arg sets. local arg_set_forms = conjugations[conj_type](args, data) if i == 1 then forms = arg_set_forms else for _, all_forms in pairs(main_to_all_verb_forms) do for _, form in ipairs(all_forms) do if arg_set_forms[form] then append_to_arg_chain(forms, all_forms[1], all_forms[1], arg_set_forms[form]) end end end end ut.insert_if_not(titles, data.title) if conj_type == "irreg" then table.insert(categories, "Russian irregular verbs") end -- For irregular verbs, if the verb didn't set a specific cat_conj_type, -- it will be the same as the conj_type and be "irreg". In that case, -- replace it with the title, which might be a proper conjugation type -- like 4a or 8c/b (and remove anything starting with a slash, to -- account for cases like 8c/b). After doing this, the cat_conj_type -- might still begin with "irreg" (for sufficiently irregular verbs that -- they can't be assigned to any of the normal classes), in which case -- we don't create a class for the verb beyond "Russian irregular verbs" -- (set above). if data.cat_conj_types[1] == "irreg" then data.cat_conj_types = {rsub(rsub(data.title, "/.*", ""), "⑨", "")} end for _, cat_conj_type in ipairs(data.cat_conj_types) do if not rmatch(cat_conj_type, "^irreg") then local class_num = rmatch(cat_conj_type, "^([0-9]+)") assert(class_num and class_num ~= "") table.insert(categories, "Russian class " .. class_num .. " verbs") table.insert(categories, "Russian class " .. cat_conj_type .. " verbs") end end end data.title = "class " .. table.concat(titles, " // ") .. (data.perf and " perfective" or " imperfective") .. (data.refl and " reflexive" or data.intr and " intransitive" or " transitive") .. (data.impers and " impersonal" or "") .. (data.iter and " iterative" or "") -- Perfective/imperfective if data.perf then table.insert(categories, "Russian perfective verbs") else table.insert(categories, "Russian imperfective verbs") end handle_forms_and_overrides(set1, forms, data) local function remove_pseudo(str) toremove = set1["asif_prefix"] or PSEUDOCONS if str == nil then return str end str = rsub(str, "^%-" .. toremove, "-") -- also handle prefix after space, e.g. in futures str = rsub(str, " %-" .. toremove, " -") return str end -- Remove pseudoconsonant we may have inserted; if no ending, insert -- "(no suffix)". for k, v in pairs(forms) do if forms[k] == "-" .. PSEUDOCONS or type(forms[k] == "table") and forms[k][1] == "-" .. PSEUDOCONS then -- Make the translit empty. forms[k] = {"(no suffix)", ""} else if type(forms[k]) == "table" then forms[k][1] = remove_pseudo(forms[k][1]) forms[k][2] = remove_pseudo(forms[k][2]) else forms[k] = remove_pseudo(forms[k]) end end end -- Catch errors in verb arguments that lead to the infinitive not matching -- page title, but only in the main namespace. local NAMESPACE = mw.title.getCurrentTitle().nsText if NAMESPACE == "" then local PAGENAME = mw.loadData("Modül:başlık başı/veri").pagename for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local inf, inf_tr = extract_russian_tr(forms[form]) if inf then inf, _ = m_table_tools.separate_notes(inf) -- remove any footnote symbols (e.g. грясти́) local inf_noaccent = com.remove_accents(inf) if inf ~= "-" then if data.refl then if rfind(inf_noaccent, "и$") then inf_noaccent = inf_noaccent .. "сь" inf = inf .. "сь" else inf_noaccent = inf_noaccent .. "ся" inf = inf .. "ся" end end if inf_noaccent ~= PAGENAME then error("Infinitive " .. inf .. " doesn't match pagename " .. PAGENAME) end end end end end -- Reflexive/intransitive/transitive if set1["reflex_stress"] then track("reflex-stress") end if data.refl then local reflex_stress = set1["reflex_stress"] or data.default_reflex_stress -- "ся́" make_reflexive(forms, reflex_stress and reflex_stress ~= "n" and reflex_stress ~= "no") table.insert(categories, "Russian reflexive verbs") elseif data.intr then table.insert(categories, "Russian intransitive verbs") else table.insert(categories, "Russian transitive verbs") end -- Impersonal if data.impers then table.insert(categories, "Russian impersonal verbs") end -- Iterative if data.iter then table.insert(categories, "Russian iterative verbs") end if data.old then make_pre_reform(forms) end finish_generating_forms(forms, data) return forms, data.title, data.perf, data.intr or data.refl, data.impers, categories, notes, data.internal_notes end local function fetch_forms(forms) local function fetch_one_form(form) local val = forms[form] local ru, tr if type(val) == "table" then ru, tr = val[1], val[2] elseif type(val) == "string" and val ~= "" and val ~= "-" then ru = val end if not ru then return nil end local ruentry, runotes = m_table_tools.get_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.get_notes(tr) end -- There shouldn't be any links. -- ruentry = m_links.remove_links(ruentry) -- There shouldn't be any vertical bars. -- ruentry = rsub(ruentry, "|", "<!>") -- if trentry then -- trentry = rsub(trentry, "|", "<!>") -- end return trentry and ruentry .. "//" .. trentry or ruentry end local vals = {} for _, proplist in ipairs(all_verb_forms) do local vallist = {} local propname = proplist[1] if not rfind(propname, "^pres_futr") then for _, prop in ipairs(proplist) do local val = fetch_one_form(prop) if val then table.insert(vallist, val) end end if #vallist > 0 then table.insert(vals, propname .. "=" .. table.concat(vallist, ",")) end end end return table.concat(vals, "|") end function export.generate_forms(frame) local arg_sets, verb_type = split_args_handle_aliases(frame) local old = frame.args["old"] or arg_sets[1]["old"] local forms, title, perf, intr, impers, categories, notes, internal_notes = export.do_generate_forms(arg_sets, verb_type, old) return fetch_forms(forms) end local function concat_vals(val) if type(val) == "table" then return table.concat(val, ",") else return val end end -- The main entry point. -- This is the only function that can be invoked from a template. function export.show(frame) local arg_sets, verb_type = split_args_handle_aliases(frame) local old = frame.args["old"] or arg_sets[1]["old"] local arg_sets_clone if test_new_ru_verb_module then -- arg_sets may be modified by do_generate_forms() arg_sets_clone = mw.clone(arg_sets) end local forms, title, perf, intr, impers, categories, notes, internal_notes = export.do_generate_forms(arg_sets, verb_type, old) -- Test code to compare existing module to new one. if test_new_ru_verb_module then local m_new_ru_verb = require("Modül:User:Benwing2/ru-verb") local newforms, newtitle, newperf, newintr, newimpers, newcategories, newnotes, newinternal_notes = m_new_ru_verb.do_generate_forms(arg_sets_clone, verb_type, old) local vals = mw.clone(forms) vals.title = title vals.perf = perf vals.intr = intr vals.impers = impers vals.categories = categories vals.notes = notes vals.internal_notes = internal_notes local newvals = mw.clone(newforms) newvals.title = newtitle newvals.perf = newperf newvals.intr = newintr newvals.impers = newimpers newvals.categories = newcategories newvals.notes = newnotes newvals.internal_notes = newinternal_notes local difconj = false for _, proplist in ipairs(all_verb_props) do for _, prop in ipairs(proplist) do local val = vals[prop] local newval = newvals[prop] -- deal with impedance mismatch between old style (plain string) -- and new style (Russian/translit array), and empty string vs. nil if not ut.contains(non_form_props, prop) then if type(val) == "string" then val = {val} end if val and val[1] == "" then val = nil end if type(newval) == "string" then newval = {newval} end if newval and newval[1] == "" then newval = nil end end -- Ignore changes in pres_futr_*, which aren't displayed if not forms_equal(val, newval) and not rfind(prop, "^pres_futr") then -- Uncomment this to display the particular case and -- differing forms. --error(prop .. " " .. (val and concat_vals(val) or "nil") .. " || " .. (newval and concat_vals(newval) or "nil")) difconj = true break end end end track(difconj and "different-conj" or "same-conj") end return make_table(forms, title, perf, intr, impers, notes, internal_notes, old) .. m_utilities.format_categories(categories, lang) end -- Implementation of template 'ru-verb cat'. function export.catboiler(frame) local SUBPAGENAME = mw.loadData("Modül:başlık başı/veri").pagename local cats = {} local cls, variant, pattern = rmatch(SUBPAGENAME, "^Russian class ([0-9]*)(°?)([abc]?) verbs") local text = nil if not cls then error("Invalid category name, should be e.g. \"Russian class 3a verbs\"") end if pattern == "" then table.insert(cats, "Russian verbs by class|" .. cls .. variant) text = "This category contains Russian class " .. cls .. " verbs." else table.insert(cats, "Russian verbs by class and accent pattern|" .. cls .. pattern) table.insert(cats, "Russian class " .. cls .. " verbs|" .. pattern) text = "This category contains Russian class " .. cls .. " verbs of " .. "accent pattern " .. pattern .. ( variant == "" and "" or " and variant " .. variant) .. ". " .. ( pattern == "a" and "With this pattern, all forms are stem-stressed." or pattern == "b" and "With this pattern, all forms are ending-stressed." or "With this pattern, the first singular present indicative and all forms " .. "outside of the present indicative are ending-stressed, while the remaining " .. "forms of the present indicative are stem-stressed.").. ( variant == "" and "" or cls == "3" and " The variant code indicates that the -н of the stem " .. "is missing in most non-present-tense forms." or " The variant code indicates that the present tense is not " .. "[[Appendix:Glossary#iotation|iotated]]. (In most verbs of this class, " .. "the present tense is iotated, e.g. иска́ть with present tense " .. "ищу́, и́щешь, и́щет, etc.)") end return text .. "\n" .. mw.getCurrentFrame():expandTemplate{title="ru-categoryTOC", args={}} .. m_utilities.format_categories(cats, lang, nil, nil, "force") end -- Implementation of poscatboiler handler for Russian verb cats. Loaded from -- [[Module:category tree/poscatboiler/data/lang-specific]]. function export.poscatboiler_verb_class_handler(cls, variant, pattern) if pattern == "" then return { description = "Russian class " .. cls .. " verbs.", breadcrumb = cls, parents = {{name = "verbs by class", sort = cls .. variant}}, } else return { description = "Russian class " .. cls .. " verbs of " .. "accent pattern " .. pattern .. ( variant == "" and "" or " and variant " .. variant) .. ". " .. ( pattern == "a" and "With this pattern, all forms are stem-stressed." or pattern == "b" and "With this pattern, all forms are ending-stressed." or "With this pattern, the first singular present indicative and all forms " .. "outside of the present indicative are ending-stressed, while the remaining " .. "forms of the present indicative are stem-stressed.") .. ( variant == "" and "" or cls == "3" and " The variant code indicates that the -н of the stem " .. "is missing in most non-present-tense forms." or " The variant code indicates that the present tense is not " .. "[[Appendix:Glossary#iotation|iotated]]. (In most verbs of this class, " .. "the present tense is iotated, e.g. иска́ть with present tense " .. "ищу́, и́щешь, и́щет, etc.)"), breadcrumb = cls .. variant .. pattern, parents = { {name = "class " .. cls .. " verbs", sort = pattern}, {name = "verbs by class and accent pattern", sort = cls .. pattern}, }, } end end --[=[ Functions for working with stems, paradigms, Russian/translit ]=] -- Combine a stem with optional translit with an ending and possibly a foonote -- symbol (which may be a tuple {RUNOTES, TRNOTES}), returning a tuple -- {RUSSIAN, TR}. local function combine(stem, tr, ending, note) if not ending or ending == "-" then return nil end local arg_status ending, arg_status = strip_arg_status_prefix(ending) if stem ~= "" and com.is_stressed(ending) then stem, tr = com.make_unstressed_once(stem, tr) end stem = arg_status .. stem if not note then return nom.concat_russian_tr(stem, tr, ending, nil, "dopair") else local runotes, trnotes = extract_russian_tr(note) local ruending, trending = nom.concat_russian_tr(ending, nil, runotes, trnotes) return nom.concat_russian_tr(stem, tr, ruending, trending, "dopair") end end -- Set an individual form PARAM in FORMS with value based on stem STEM (with -- optional translit TR), ENDINGS (either a single string or a list of strings) -- and NOTE (nil, a string, or a tuple {RUSSIAN, TR}). If there are multiple -- endings listed, they will go successively into PARAM, PARAM2, etc. -- (e.g. past_m, past_m2, etc.). local function set_form(forms, param, stem, tr, endings, note) if type(endings) ~= "table" then endings = {endings} end local entries = {} for _, val in ipairs(endings) do ut.insert_if_not(entries, combine(stem, tr, val, note)) end set_arg_chain(forms, param, param, entries) end -- Append to an individual form PARAM in FORMS with value based on stem STEM -- (with optional translit TR), ENDINGS (either a single string or a list of -- strings) and NOTE (nil, a string, or a tuple {RUSSIAN, TR}). If there are -- multiple endings listed, they will go successively into PARAM, PARAM2, etc. -- (e.g. past_m, past_m2, etc.), provided there are no existing forms already -- present. Duplicate forms aren't inserted. local function append_form(forms, param, stem, tr, endings, note) if type(endings) ~= "table" then endings = {endings} end for _, val in ipairs(endings) do append_to_arg_chain(forms, param, param, combine(stem, tr, val, note)) end end local function append_pres_futr(forms, stem, tr, sg1, sg2, sg3, pl1, pl2, pl3, note) append_form(forms, "pres_futr_1sg", stem, tr, sg1, note) append_form(forms, "pres_futr_2sg", stem, tr, sg2, note) append_form(forms, "pres_futr_3sg", stem, tr, sg3, note) append_form(forms, "pres_futr_1pl", stem, tr, pl1, note) append_form(forms, "pres_futr_2pl", stem, tr, pl2, note) append_form(forms, "pres_futr_3pl", stem, tr, pl3, note) end local function append_participles_2stem(forms, pres_stem, pres_tr, past_stem, past_tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, pres_note, past_note) append_form(forms, "pres_actv_part", pres_stem, pres_tr, pres_actv, pres_note) append_form(forms, "pres_pasv_part", pres_stem, pres_tr, pres_pasv, pres_note) append_form(forms, "pres_adv_part", pres_stem, pres_tr, pres_adv, pres_note) append_form(forms, "past_actv_part", past_stem, past_tr, past_actv, past_note) append_form(forms, "past_adv_part", past_stem, past_tr, past_adv, past_note) append_form(forms, "past_adv_part_short", past_stem, past_tr, past_adv_short, past_note) end local function append_participles(forms, stem, tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, note) append_participles_2stem(forms, stem, tr, stem, tr, pres_actv, pres_pasv, pres_adv, past_actv, past_adv, past_adv_short, note, note) end local function set_ppp(forms, stem, tr, ending, note) set_form(forms, "past_pasv_part", stem, tr, ending, note) end local function append_ppp(forms, stem, tr, ending, note) append_form(forms, "past_pasv_part", stem, tr, ending, note) end local function append_imper(forms, stem, tr, sg, pl, note) append_form(forms, "impr_sg", stem, tr, sg, note) append_form(forms, "impr_pl", stem, tr, pl, note) end local function set_past(forms, stem, tr, m, f, n, pl, note) set_form(forms, "past_m", stem, tr, m, note) set_form(forms, "past_f", stem, tr, f, note) set_form(forms, "past_n", stem, tr, n, note) set_form(forms, "past_pl", stem, tr, pl, note) end local function append_past(forms, stem, tr, m, f, n, pl, note) append_form(forms, "past_m", stem, tr, m, note) append_form(forms, "past_f", stem, tr, f, note) append_form(forms, "past_n", stem, tr, n, note) append_form(forms, "past_pl", stem, tr, pl, note) end -- Prepend a possibly-stressed prefix to all forms; if prefix is stressed, -- destress the forms before prepending. FIXME: Should support explicit -- manual translit. local function prepend_prefix(forms, prefix, pre_two_cons_prefix) pre_two_cons_prefix = pre_two_cons_prefix or prefix local stressed_prefix = com.is_stressed(prefix) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) if tr then error("Explicit manual translit not yet supported") end -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then if stressed_prefix then ru = com.make_unstressed(ru) end if rfind(ru, "^[" .. com.cons .. "][" .. com.cons .. "]") then forms[key] = pre_two_cons_prefix .. ru else forms[key] = prefix .. ru end end end end -- Apply regex substitution FROM -> TO to all forms. FIXME: Should support -- explicit manual translit. local function rsub_forms(forms, from, to) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) if tr then error("Explicit manual translit not yet supported") end -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then forms[key] = rsub(ru, from, to) end end end local variant_to_title = { ["[(2)]"] = "[②]", ["(2)"] = "②", ["[(3)]"] = "[③]", ["(3)"] = "③", ["[(4)]"] = "[④]", ["(4)"] = "④", ["[(5)]"] = "[⑤]", ["(5)"] = "⑤", ["[(6)]"] = "[⑥]", ["(6)"] = "⑥", ["[(7)]"] = "[⑦]", ["(7)"] = "⑦", ["[(8)]"] = "[⑧]", ["(8)"] = "⑧", ["(9)"] = "⑨", ["щ"] = "(-щ-)", ["ё"] = "(-ё-)", ["о"] = "(-о-)", ["жд"] = "(-жд-)", } local function prepare_past_stress_indicator(past_stress) if not past_stress or past_stress == "a" then return "" end past_stress = rsub(past_stress, "%(1%)", "①") past_stress = rsub(past_stress, "(.),%1①", "%1[①]") past_stress = rsub(past_stress, "(.)①,%1", "%1[①]") past_stress = rsub(past_stress, "''", "&#39;&#39;") past_stress = rsub(past_stress, "-nd", "") past_stress = rsub(past_stress, "-bd", "") return "/" .. past_stress end local function parse_variants(data, variants, allowed) -- Need to set these to nil in case of multiple arg sets data.imper_variant = nil data.var4 = nil data.var5 = nil data.var6 = nil data.ppp = nil data.var9 = nil data.shch = nil data.yo = nil data.o = nil data.zhd = nil data.star = nil variants = variants or "" local variant_title = "" if variants ~= "" then -- short-circuit the most common case -- Only recognize * variant for long-variant prefix at the beginning -- of the variant code block (where it gets moved if it's in the -- middle of the conjugation type, as it normally is) because a * -- also occurs in b*, a past stress variant code. if rfind(variants, "^%*") then -- Specify that the present/future tense has extra -о in the prefix: -- types 9*b (e.g. растере́ть, futr_1sg разотру́) and 11*b (e.g. изли́ть, -- futr_1sg изолью́). It can also occur with type 7*b (in -че́сть, -- e.g. счесть, сочту́; расче́сть, разочту́) and type 8*b (in -же́чь, e.g. -- сжечь, сожгу́) but these are always irregular and require the -- present tense to be specified explicitly. It can also occur -- with type 14*b (e.g. размя́ть, разомну́; сжать, сожну́; подожа́ть, подожму́), -- but for these verbs the present tense is unpredictable and -- must be specified explicitly. -- -- This can also occur where the extra -о occurs in the infinitive -- and past, but not the present tense: type 5*c (in -гна́ть, e.g. -- согна́ть, сгоню́; разогна́ться, разгоню́сь), type 6*c (in -стла́ть, e.g. -- подостла́ть, подстелю́; разостла́ть, расстелю́), type 6°*c -- (in -зва́ть, -бра́ть, -дра́ть, e.g. подозва́ть, подзову́; разобра́ться, разберу́сь); -- but these are always irregular and require the present tense -- to be specified explicitly. if not ut.contains(allowed, "*") then error("Variant " .. var .. " not allowed for this verb class") end data.star = true variants = rsub(variants, "^*", "") end -- Allow brackets around both 5 and 6, e.g. [(5)(6)] variants = rsub(variants, "%[(%([56]%))(%([56]%))%]", "[%1][%2]") -- Handle all remaining variants. We do this using an rsub() function, -- where we pull out, parse and remove each variant in turn. variants = rsub(variants, "(%[?%(?[23456789ёощийьж+][дp]?%)?%]?)", function(var) if ut.contains({"(2)", "[(2)]", "(3)", "[(3)]", "и", "й", "ь"}, var) then if data.imper_variant then error("Saw two imperative variants " .. data.imper_variant .. " and " .. var) end local is_23 = ut.contains({"(2)", "[(2)]", "(3)", "[(3)]"}, var) if is_23 and not ut.contains(allowed, "23") or not is_23 and not ut.contains(allowed, "и") then error("Variant " .. var .. " not allowed for this verb class") end data.imper_variant = var elseif ut.contains({"(4)", "[(4)]"}, var) then if data.var4 then error("Saw two variant-4 specs " .. data.var4 .. " and " .. var) end if not ut.contains(allowed, "4") then error("Variant " .. var .. " not allowed for this verb class") end data.var4 = var == "(4)" and "req" or "opt" elseif ut.contains({"(5)", "[(5)]"}, var) then if data.var5 then error("Saw two variant-5 specs " .. data.var5 .. " and " .. var) end if not ut.contains(allowed, "5") then error("Variant " .. var .. " not allowed for this verb class") end data.var5 = var == "(5)" and "req" or "opt" elseif ut.contains({"(6)", "[(6)]"}, var) then if data.var6 then error("Saw two variant-6 specs " .. data.var6 .. " and " .. var) end if not ut.contains(allowed, "6") then error("Variant " .. var .. " not allowed for this verb class") end data.var6 = var == "(6)" and "req" or "opt" elseif ut.contains({"(7)", "[(7)]", "(8)", "[(8)]", "+p"}, var) then if data.shouldnt_have_ppp then error("Shouldn't specify past passive participle with reflexive or intransitive verbs, if it's needed use has_ppp=y") end if data.ppp then error("Saw two past passive participle specs " .. data.ppp .. " and " .. var) end if ut.contains({"(7)", "[(7)]"}, var) and not ut.contains(allowed, "7") or ut.contains({"(8)", "[(8)]"}, var) and not ut.contains(allowed, "8") or var == "+p" and not ut.contains(allowed, "+p") then error("Variant " .. var .. " not allowed for this verb class") end data.ppp = var elseif var == "(9)" then if data.var9 then error("Saw (9) twice") end if not ut.contains(allowed, "9") then error("Variant " .. var .. " not allowed for this verb class") end data.var9 = true elseif var == "щ" then -- specify that the 1sg pres/futr and past passive participle -- of class 4/5/6 verbs iotate -т to -щ instead of -ч; cf. -- похи́тить (похи́щу) (4a), защити́ть (защищу́) (4b), -- поглоти́ть (поглощу́) (4c), клевета́ть (клевещу́) (6c) if data.shch then error("Saw щ twice") end if not ut.contains(allowed, "щ") then error("Variant " .. var .. " not allowed for this verb class") end data.shch = "щ" elseif var == "ё" then -- specify that the past passive participle has ё instead of е if data.yo then error("Saw ё twice") end if not ut.contains(allowed, "ё") then error("Variant " .. var .. " not allowed for this verb class") end data.yo = true elseif var == "о" then -- specify that the past passive participle has о instead of е -- NOTE: Not currently allowed as a user-specifiable variant if data.o then error("Saw о twice") end if not ut.contains(allowed, "о") then error("Variant " .. var .. " not allowed for this verb class") end data.o = true elseif var == "жд" then -- specify that the past passive participle of class 4/5/6 verbs -- iotates -д to -жд instead of -ж if data.zhd then error("Saw жд twice") end if not ut.contains(allowed, "жд") then error("Variant " .. var .. " not allowed for this verb class") end data.zhd = true else error("Unrecognized variant spec: " .. var) end variant_title = variant_title .. (variant_to_title[var] or "") return "" end) variant_title = rsub(variant_title, "%[⑤%]%[⑥%]", "[⑤⑥]") end if variants ~= "" and not ut.contains(allowed, "past") then error("Past stress " .. variants .. " not allowed for this verb class") end if data.yo and not data.ppp then error("Variant ё specified without calling for past passive participle") end if data.o and not data.ppp then error("Variant о specified without calling for past passive participle") end if data.zhd and not data.ppp then error("Variant жд specified without calling for past passive participle") end if data.perf and not data.ppp and not data.ppp_override and not data.shouldnt_have_ppp and not data.impers then error("For perfective transitive verbs, need to specify past passive participle by variant or override; use |ppp=- if no such participle") end data.past_stress = variants == "" and "a" or rsub(variants, "/", "") data.title = data.title .. prepare_past_stress_indicator(data.past_stress) .. variant_title if data.star then data.title = rsub(data.title, "^([0-9]+°?)", "%1*") end -- If there's an override of past_pasv_part, generate the normal participle -- so we can determine whether the override is irregular. But set a flag -- so we erase any automatically generated past passive participles that -- aren't overridden. This happens for example in обнять, where there are -- two automatically generated past passive participles but a single -- ppp=о́внятый override. if not data.ppp and data.main_ppp_override then data.ppp = "+p" data.ppp_auto_generated = true end end local function set_past_by_stress(forms, past_stresses, prefix, prefixtr, base, basetr, args, data, no_pastml, note) -- If there isn't manual translit for the prefix, we need to supply it -- if there's manual translit for the base, because we often concatenate -- prefix to the base. local prefixtr = prefixtr or basetr and com.translit(prefix) for _, past_stress in ipairs(rsplit(past_stresses, ",")) do local pastml = no_pastml and "" or "л" local stressed_prefixtr if prefix == "пере" then stressed_prefix = "пе́ре" stressed_prefixtr = "pe" .. AC .. "re" elseif prefix == "раз" then stressed_prefix = "ро́з" stressed_prefixtr = "ro" .. AC .. "z" elseif prefix == "рас" then -- Does this ever occur? stressed_prefix = "ро́с" stressed_prefixtr = "ro" .. AC .. "s" elseif prefix == "ра" and rfind(base, "^[сз]") then -- Type 9/11/14/16 with automatically split prefix; may never happen. stressed_prefix = "ро́" stressed_prefixtr = "ro" .. AC else stressed_prefix, stressed_prefixtr = com.make_ending_stressed(prefix, prefixtr) end -- Normally the base is stressed and the prefix isn't, but it could -- be the other way around, e.g. in запереть and запереться, where -- the stress on the prefix is used to get prefix-stressed participles. -- To deal with this, we usually combine base and prefix unchanged, -- but in combination with stressed_prefix we always want an unstressed -- base, and when a stressed -ся́ is called for, we want both of them -- unstressed. local ubase, ubasetr = com.make_unstressed(base, basetr) local uprefix, uprefixtr = com.make_unstressed(prefix, prefixtr) local prefixbase = prefix .. base local prefixbasetr = basetr and prefixtr .. basetr local stressed_prefix_ubase = stressed_prefix .. ubase local stressed_prefix_ubasetr = ubasetr and stressed_prefixtr .. ubasetr local uprefixubase = uprefix .. ubase local uprefixubasetr = ubasetr and uprefixtr .. ubasetr if past_stress == "a" then -- (/под/пере/при/по)забы́ть, раздобы́ть, (/пере/по)забы́ться append_past(forms, prefixbase, prefixbasetr, pastml, "ла", "ло", "ли", note) elseif past_stress == "a(1)" then -- вы́дать, вы́быть, etc.; also проби́ть with the meaning -- "to strike (of a clock)" (which is a(1),a or similar) append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, "ла", "ло", "ли", note) elseif past_stress == "b" then append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", "ло́", "ли́", note) elseif past_stress == "b*" then if not data.refl then error("Only reflexive verbs can take past stress variant " .. past_stress) end -- See comment in type c''. We want to see whether we actually -- added an argument, and if so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. (note or ""))) if argset and not args[argset] and not data.impers then data.default_reflex_stress = "ся́" end append_past(forms, prefixbase, prefixbasetr, {}, "ла́", "ло́", "ли́", note) elseif past_stress == "c" then -- изда́ть, возда́ть, сдать, пересозда́ть, воссозда́ть, надда́ть, наподда́ть, etc. -- быть, избы́ть, сбыть -- клясть, закля́сть append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", "ло", "ли", note) elseif past_stress == "c(1)" then -- прибы́ть, убы́ть -- прокля́сть -- also, c(1),c: -- зада́ть, обда́ть, отда́ть, подда́ть, переда́ть (пе́редал), преда́ть, прода́ть, разда́ть (ро́здал), созда́ть, etc. -- отбы́ть, побы́ть, пробы́ть -- also, c,c(1): -- добы́ть -- Because the prefix may vary depending on stress (esp. for -- раздать [ро́здал/раздала́]), we need to separate the endings that -- take the stressed prefix and those that take the unstressed -- prefix with stressed ending. append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) append_past(forms, prefixbase, prefixbasetr, {}, "ла́", {}, {}, note) elseif past_stress == "c'" then -- дать --same with "взять" append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", {"ло", "ло́"}, "ли", note) elseif past_stress == "c''" or past_stress == "c''-nd" or past_stress == "c''-bd" then if not data.refl then error("Only reflexive verbs can take past stress variant " .. past_stress) end -- c'' (-ся́ dated): all verbs in -да́ться; избы́ться, сбы́ться; all verbs in -кля́сться -- c''-nd (-ся́ not dated): various verbs in -ня́ться per Zaliznyak -- c''-bd (-ся́ becoming dated): various verbs in -ня́ться per ruwikt local note_symbol = past_stress == "c''-nd" and "" or next_note_symbol(data) append_past(forms, prefixbase, prefixbasetr, pastml, "ла́", {"ло́", "ло"}, {"ли́", "ли"}) -- We want to see whether we actually added an argument, and if -- so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. note_symbol .. (note or ""))) -- Only display the internal note and set the default reflex -- stress if the form with the note will be displayed (i.e. not -- impersonal, and no override of this form). FIXME: We should -- have a more general mechanism to check for this. if not args[argset] and not data.impers then ut.insert_if_not(data.internal_notes, past_stress == "c''" and note_symbol .. " Dated." or past_stress == "c''-bd" and note_symbol .. " Becoming dated." or nil) data.default_reflex_stress = "ся́" end elseif past_stress == "c''(1)" then -- запере́ться -- See comment in type c''. We want to see whether we actually -- added an argument, and if so, where. local argset = append_to_arg_chain(forms, "past_m", "past_m", combine(uprefixubase, uprefixubasetr, pastml .. (note or ""))) if argset and not args[argset] and not data.impers then data.default_reflex_stress = "ся́" end append_past(forms, prefixbase, prefixbasetr, {}, "ла́", "ло́", "ли́", note) append_past(forms, stressed_prefix_ubase, stressed_prefix_ubasetr, pastml, {}, "ло", "ли", note) else error("Unrecognized past-stress value " .. past_stress .. ", should be a, a(1), b, b*, c, c(1), c', c'', c''-nd, c''-bd, c''(1) or comma-separated list") end end end -- Split a verb stem into a possibly multisyllabic prefix (пере-, переиз-, -- воссоз-, повы́-, etc.) and a single-syllable main verb (-тер-, -ли́-, -гре́-, -- etc.). Normally the splitting is done simply by looking for alternating -- vowel/consonant sequences, meaning that e.g. разгре́ will be split as -- ра + згре́ and растер will be split as ра + стер. For most purposes, this -- doesn't matter, but for the * variant it does; in that case, if it is -- known that the main verb base always begins with a single consonant, -- specify SINGLE_CONS_BASE and then e.g. растер will be split as рас + тер. local function split_monosyllabic_main_verb(ru, tr, single_cons_base) local rusyl, trsyl = com.split_syllables(ru, tr) local last_ru = rusyl[#rusyl] local last_tr = trsyl and trsyl[#trsyl] table.remove(rusyl, #rusyl) local prefix_ru = table.concat(rusyl, "") local prefix_tr if trsyl then table.remove(trsyl, #trsyl) prefix_tr = table.concat(trsyl, "") end if single_cons_base then local cons_to_move, rest = rmatch(last_ru, "^([" .. com.cons .. "]+)([" .. com.cons .. "].*)$") if cons_to_move then prefix_ru = prefix_ru .. cons_to_move last_ru = rest end if last_tr then cons_to_move, rest = rmatch(last_tr, "^([" .. com.tr_cons .. "]+)([" .. com.tr_cons .. "].*)$") if cons_to_move then prefix_tr = prefix_tr .. cons_to_move last_tr = rest end end end return prefix_ru, prefix_tr, last_ru, last_tr end local function split_known_main_verb(arg, mains) -- Given an argument (which may be RUSSIAN//TR), split the prefix from -- the main verb, which should be one of the verbs in MAINS (which can be -- a -- single verb or a list of verbs, but in either case all verbs -- need to be stressed). This correctly handles stressed and unstressed -- prefixes. local stem, tr = nom.split_russian_tr(arg) if type(mains) ~= "table" then mains = {mains} end for _, main in ipairs(mains) do assert(com.is_stressed(main)) if rfind(stem, main .. "$") then stem, tr = nom.strip_ending(stem, tr, main) if com.is_stressed(stem) then error("Two stresses in " .. arg) end return stem, tr, main, nil end main = com.make_unstressed_once(main) if rfind(stem, main .. "$") then stem, tr = nom.strip_ending(stem, tr, main) if com.is_unstressed(stem) then error("No stresses in " .. arg) end return stem, tr, main, nil end end if #mains == 1 then error("Argument " .. arg .. " doesn't end in " .. mains[1]) else error("Argument " .. arg .. " doesn't end in any of " .. table.concat(mains, ",")) end end local function construct_long_prefix_variant(prefix) if rfind(prefix, "рас$") then return rsub(prefix, "рас$", "разо") end if rfind(prefix, "ис$") then return rsub(prefix, "ис$", "изо") end if rfind(prefix, "вс$") then return rsub(prefix, "вс$", "взо") end return prefix .. "о" end local function append_imper_by_variant(forms, stem, tr, variant, verbclass, note) local vowel_stem = is_vowel_stem(stem) local stress = rmatch(verbclass, "([abc])$") if not stress then error("Unrecognized verb class '" .. verbclass .. "', should end with a, b or c") end local longend = stress == "a" and "и" or "и́" local shortend = vowel_stem and (com.is_unstressed(stem) and "́й" -- accent on previous vowel or "й") or "ь" local function append_short_imper() append_imper(forms, stem, tr, shortend, shortend .. "те", note) end local function append_long_imper() append_imper(forms, stem, tr, longend, longend .. "те", note) end if variant and variant ~= "" then track("explicit-imper") track("explicit-imper/" .. verbclass) end if variant == "(2)" then -- use short variants with вы́- (for these verbs, long is expected) if not rfind(stem, "^вы́-") then error("Should only specify imperative variant (2) with verbs in вы́-, not " .. stem) end append_short_imper() elseif variant == "[(2)]" then -- use both long and short variants append_long_imper() append_short_imper() elseif variant == "(3)" then -- long in singular, short in plural append_imper(forms, stem, tr, longend, shortend .. "те", note) elseif variant == "[(3)]" then -- long and short in singular, short in plural append_imper(forms, stem, tr, {longend, shortend}, shortend .. "те", note) elseif variant == "ь" or variant == "й" then -- short variants wanted append_short_imper() elseif variant == "и" then -- long variants wanted append_long_imper() else assert(not variant or variant == "") if vowel_stem then if verbclass == "4b" or verbclass == "4c" or ( verbclass == "4a" and rfind(stem, "^вы́-")) then append_long_imper() else append_short_imper() end else -- consonant stem if stress == "b" or stress == "c" then append_long_imper() else assert(stress == "a") -- "и" after вы́-, e.g. вы́садить -- "и" after final щ, e.g. тара́щиться (although this particular -- verb has a [(3)] spec attached to it) if rfind(stem, "^вы́-") or rfind(stem, "щ$") or -- "и" after two consonants in a row (мо́рщить, зафре́ндить) rfind(stem, "[бвгджзклмнпрстфхцчшщь][бвгджзклмнпрстфхцчшщ]$") then append_long_imper() else -- "ь" after a single consonant (бре́дить) append_short_imper() end end end end end -- Compute the past passive participle stem for verbs that require it to be -- iotated (class 4, and class 5 in -еть). local function iotated_ppp(data, stem, tr) local iotated_stem, iotated_tr if data.zhd then local subbed iotated_stem, subbed = rsubb(stem, "з?д$", "жд") if not subbed then error("Variant -жд- specified but stem " .. stem .. " doesn't end in -д") end if tr then iotated_tr, subbed = rsubb(tr, "z?d$", "žd") if not subbed then error("Variant -жд- specified but translit " .. tr .. " doesn't end in -d") end end else iotated_stem, iotated_tr = com.iotation(stem, tr, data.shch) end return iotated_stem, iotated_tr end -- Set the past passive participle of verbs where the stress is moved left -- from the ending by one syllable (if possible) if the ending is stressed, -- otherwise left as-is (except class 1a in -е́ть, which has ending-stressed -- -ённый). This applies to classes 1, 2, 3, 5, 6, 10 and 13. The stem comes -- from the infinitive, iotated in class 5 -еть/-ѣть verbs. The participle -- ending is -анный/-янный for verbs in -ать/-ять, -енный/-ённый for verbs in -еть, -- -ѣнный/-ѣ̈нный for verbs in -ѣть, otherwise -тый. local function set_moving_ppp(forms, data) if not data.ppp then return end -- NOTE: No need to check for multiple infinitives because no verbs have -- them normally, and we probably don't want to check for overrides here -- (e.g. it would break достичь and related verbs, which have participles -- based on the infinitive достигнуть). local infinitive, infinitivetr = extract_russian_tr(forms["infinitive"]) local stem, ending = rmatch(infinitive, "^(.*)([аеѣоуя]́?ть)$") if not stem then error("Strange infinitive " .. infinitive .. " when trying to create participle") end local tr, endingtr if infinitivetr then if ending == "ять" or ending == "я́ть" then tr, endingtr = rmatch(infinitivetr, "^(.*)(ja" .. AC .. "?tʹ)$") else tr, endingtr = rmatch(infinitivetr, "^(.*)([aeěou]" .. AC .. "?tʹ)$") end if not tr then error("Translit " .. infinitivetr .. " doesn't match Cyrillic " .. infinitive) end end local ending_vowel = usub(ending, 1, 1) local ppptype = data.ppp if com.is_nonsyllabic(stem) then -- e.g. 3b гну́ть (гну́тый); but not -нуть (type 3a, as a suffix) ppptype = "(7)" end if ut.contains({"5a", "5b", "5c"}, data.conj_type) and (ending_vowel == "е" or ending_vowel == "ѣ") then stem, tr = iotated_ppp(data, stem, tr) end if not com.is_stressed(stem) then stem, tr = com.make_ending_stressed(stem, tr) end if data.o then -- цев -> цо́в, e.g. (об)лицева́ть -> (об)лицо́ванный stem = rsub(stem, "е́", "о́") -- Cyrillic if tr then tr = rsub(tr, "e" .. AC, "o" .. AC) -- Latin end elseif data.yo then -- ё occurs with e.g. 1a наверста́ть (навёрстанный) -- ё occurs with e.g. 3b поверну́ть (повёрнутый) -- ё occurs with e.g. 5b лежа́ть (лёжанный) but not with 5c держа́ть -- (де́ржанный) -- ё occurs always with class 2 in -ева́ть, e.g. -- (за)тушева́ть ((за)тушёванный) and (за)клева́ть ((за)клёванный) local subbed stem, subbed = rsubb(stem, "е́", "ё") -- Cyrillic if not subbed and data.old then stem, subbed = rsub(stem, "ѣ́", "ѣ̈") end if not subbed then error("No stressed е" .. (data.old and " or ѣ" or "") .. " in stem " .. stem .. " to replace with ё" .. (data.old and " or ѣ̈" or "") .. " when trying to create participle") end if tr then tr, subbed = rsub(tr, "j[eě]" .. AC, "jo" .. AC) -- Latin if not subbed then tr, subbed = rsub(tr, "[eě]" .. AC, "jo" .. AC) -- Latin end if not subbed then error("No stressed е in translit " .. tr .. " to replace with jo when trying to create participle") end end end if data.conj_type == "1a" and ending_vowel == "е" then -- 1a, only одоле́ть, преодоле́ть, verbs in -печатле́ть set_ppp(forms, stem, tr, "ённый") elseif data.conj_type == "1a" and ending_vowel == "ѣ" then set_ppp(forms, stem, tr, "ѣ̈нный") else local stressed_ending, unstressed_ending if ending_vowel == "е" then stressed_ending = "ённый" unstressed_ending = "енный" elseif ending_vowel == "ѣ" then stressed_ending = "ѣ̈нный" unstressed_ending = "ѣнный" else local ppp_ending = (ending_vowel == "а" or ending_vowel == "я") and "нный" or "тый" stressed_ending = ending_vowel .. AC .. ppp_ending unstressed_ending = ending_vowel .. ppp_ending end set_ppp(forms, stem, tr, -- (7) occurs with 1a обуя́ть (обуя́нный) ppptype == "(7)" and stressed_ending or -- [(7)] -- when does it occur? may only occur in class 4 ppptype == "[(7)]" and {unstressed_ending, stressed_ending} or unstressed_ending) end end -- Iterate over the values of a property (e.g. past_m, past_f), handling -- overrides properly. Call FN on each one, passing in RU, TR, NOTE. local function iterate_over_prop(forms, args, prop, fn) for _, form in ipairs(main_to_all_verb_forms[prop]) do local ru, tr if args[form] then local orig_forms = {} for _, form2 in ipairs(main_to_all_verb_forms[prop]) do if forms[form2] then table.insert(orig_forms, forms[form2]) end end local override = parse_and_stress_override(form, args[form], forms[form], orig_forms) ru, tr = extract_russian_tr(override) end if (not ru or ru == "" or ru == "-") and forms[form] then ru, tr = extract_russian_tr(forms[form]) end -- skip unstressed forms (may occur in the past_m when a stressed -- reflexive -ся́ should occur; these occur only in запереться and -- опереться, where they're used to generate the past active part -- and past adverbial part, and end-stressed forms shouldn't be -- generated) if ru and ru ~= "" and ru ~= "-" and not com.is_unstressed(ru) then local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) end fn(ruentry, trentry, {runotes, trnotes}) end end end -- Set the past passive participle for those classes where it is derived -- from the past tense masculine singular (9, 11, 12, 14, 15, 16). We need -- to apply any relevant overrides. local function set_ppp_from_past_m(forms, args, data) if not data.ppp then return end iterate_over_prop(forms, args, "past_m", function(ru, tr, note) if rfind(ru, "л$") then ru = rsub(ru, "л$", "") if tr then tr = rsub(tr, "l$", "") end end append_ppp(forms, ru, tr, "тый", note) end) end -- Set the past passive participle for class-4 verbs. local function set_class_4_ppp(forms, data, stem, tr, vclass) if not data.ppp then return end local iotated_stem, iotated_tr = iotated_ppp(data, stem, tr) vclass = vclass or data.conj_type if vclass == "4b" then local stressed_iotated_stem, stressed_iotated_tr = com.make_ending_stressed(iotated_stem, iotated_tr) set_ppp(forms, stressed_iotated_stem, stressed_iotated_tr, -- (8) occurs with 4b скрои́ть (скро́енный) data.ppp == "(8)" and "енный" or -- [(8)] occurs with 4b разгроми́ть (разгромлённый, разгро́мленный) data.ppp == "[(8)]" and {"ённый", "енный"} or "ённый") else set_ppp(forms, iotated_stem, iotated_tr, -- (7) occurs with 4c раздели́ть (разделённый) data.ppp == "(7)" and "ённый" or -- [(7)] occurs with 4a осве́домить (осве́домленный, осведомлённый) -- [(7)] occurs with 4c иссуши́ть (иссу́шенный, иссушённый) data.ppp == "[(7)]" and {"енный", "ённый"} or "енный") end end -- Set the past passive participle for class-7 and class-8 verbs. These -- form the PPP by adding to the base of the 3sg pres/futr (i.e. minus -- -ет/-ёт). The stress follows the stress of the past singular feminine. -- Only types a, a(1) and b exist, meaning that if the past singular feminine -- is ending-stressed then the PPP ending is -ённый, otherwise it is -енный -- with the stress of the 3sg pres/futr base preserved (and added to the -- last syllable if the base has no stress, as in 7b укра́сть, 3sg украдёт, -- fem sg past укра́ла, PPP укра́денный). local function set_class_7_8_ppp(forms, args, data) if not data.ppp then return end local sg3_bases = {} -- Extract 3sg bases. There may be more than one possible form, e.g. in -- обокра́сть, so support this. -- FIXME: We don't support checking for overrides here; doing so isn't -- overly hard but is a bit tricky because the overrides will be either -- pres_3sg or futr_3sg, depending on the aspect of the verb. -- FIXME: We don't support manual translit here, because neither 7 nor 8 -- support it elsewhere. for _, form in ipairs(main_to_all_verb_forms["pres_futr_3sg"]) do local ru, tr if forms[form] then ru, tr = extract_russian_tr(forms[form]) end if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) ruentry = rsub(ruentry, "[её]т$", "") if com.is_unstressed(ruentry) then ruentry = com.make_ending_stressed(ruentry) end ut.insert_if_not(sg3_bases, {ruentry, runotes}) end end -- Here we do the same rigmarole as in set_ppp_from_past_m(), to respect -- any past_f overrides that might have been set. It's unlikely that -- there is more than one possible form but we support it. iterate_over_prop(forms, args, "past_f", function(ru, tr, note) for _, base_and_notes in ipairs(sg3_bases) do local base, notes = base_and_notes[1], base_and_notes[2] append_ppp(forms, base, nil, -- check if past_f is ending-stressed rfind(ru, AC .. "$") and "ённый" or "енный", notes) end end) end --[=[ Conjugation functions ]=] conjugations["1a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7", "ё"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) if stem == "-" and not tr then -- Template space; leave it else stem, tr = nom.strip_ending(stem, tr, "ть") end no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "ть") append_participles(forms, stem, tr, "ющий", "емый", "я", "вший", "вши", "в") set_moving_ppp(forms, data) present_je(forms, stem, tr, "a") append_imper(forms, stem, tr, "й", "йте") set_past(forms, stem, tr, "л", "ла", "ло", "ли") return forms end local function guts_of_2(args, data) local forms = {} local inf_stem, inf_tr = nom.split_russian_tr(get_stressed_arg(args, 2)) inf_stem, inf_tr = nom.strip_ending(inf_stem, inf_tr, "ть") no_stray_args(args, 2) local pres_stem, pres_tr = inf_stem, inf_tr local variants = args[1] or "" parse_variants(data, variants, {"+p", "7"}) -- If stem ends in -ева́ть and a past passive participle is called for -- with stress on the -е-, automatically set -о- or -ё- as required. if data.ppp and data.ppp ~= "(7)" then if rfind(inf_stem, "цева́") then if data.ppp == "[(7)]" then -- FIXME. Theoretically we should support this but there -- aren't any verbs requiring it. It won't work properly -- currently because we need the о to appear only when -- stressed. error("Variant [(7)] not supported for class 2") end -- цев -> цо́в, e.g. (об)лицева́ть -> (об)лицо́ванный data.o = true data.title = data.title .. "(-о-)" elseif rfind(inf_stem, "ева́") then data.yo = true data.title = data.title .. "(-ё-)" end end -- all -ова- change to -у- pres_stem = rsub(pres_stem, "о(́?)ва(́?)$", "у%1%2") pres_tr = pres_tr and rsub(pres_tr, "o(́?)va(́?)$", "u%1%2") -- -ева- change to -ю- after most consonants and vowels, to -у- after hissing sounds and ц if rfind(pres_stem, "[бвгдзклмнпрстфхь" .. com.vowel .. AC .. "]е(́?)ва(́?)$") then pres_stem = rsub(pres_stem, "е(́?)ва(́?)$", "ю%1%2") pres_tr = pres_tr and rsub(pres_tr, "e(́?)va(́?)$", "ju%1%2") elseif rfind(pres_stem, "[жцчшщ]е(́?)ва(́?)$") then pres_stem = rsub(pres_stem, "е(́?)ва(́?)$", "у%1%2") pres_tr = pres_tr and rsub(pres_tr, "e(́?)va(́?)$", "u%1%2") end forms["infinitive"] = combine(inf_stem, inf_tr, "ть") if data.conj_type == "2a" then append_participles_2stem(forms, pres_stem, pres_tr, inf_stem, inf_tr, "ющий", "емый", "я", "вший", "вши", "в") present_je(forms, pres_stem, pres_tr, "a") else append_participles_2stem(forms, pres_stem, pres_tr, inf_stem, inf_tr, "ю́щий", "-", "я́", "вший", "вши", "в") present_je(forms, pres_stem, pres_tr, "b") end set_moving_ppp(forms, data) append_imper(forms, pres_stem, pres_tr, "й", "йте") set_past(forms, inf_stem, inf_tr, "л", "ла", "ло", "ли") return forms end conjugations["2a"] = function(args, data) return guts_of_2(args, data) end conjugations["2b"] = function(args, data) return guts_of_2(args, data) end conjugations["3°a"] = function(args, data) local forms = {} -- (5), [(6)] or similar; imperative indicators parse_variants(data, args[1], {"5", "6", "23", "и", "+p", "7", "ё"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = nom.strip_ending(stem, tr, "нуть") local vowel_stem = is_vowel_stem(stem) no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "нуть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "нущий", "-", "-", data.var6 == "req" and "нувший" or data.var6 == "opt" and (vowel_stem and {"вший", "нувший"} or {"ший", "нувший"}) or vowel_stem and "вший" or "ший", data.var6 == "req" and "нувши" or data.var6 == "opt" and (vowel_stem and {"вши", "нувши"} or {"ши", "нувши"}) or vowel_stem and "вши" or "ши", data.var6 == "req" and "нув" or data.var6 == "opt" and (vowel_stem and {"в", "нув"} or "нув") or vowel_stem and "в" or "-") set_moving_ppp(forms, data) present_e_a(forms, stem .. "н", tr and tr .. "n") append_imper_by_variant(forms, stem .. "н", tr and tr .. "n", data.imper_variant, "3°a") forms["past_m"] = data.var5 and combine(stem, tr, "нул") or "-" forms["past_m_short"] = data.var5 ~= "req" and combine(stem, tr, (vowel_stem and "л" or "")) or nil forms["past_f_short"] = combine(stem, tr, "ла") forms["past_n_short"] = combine(stem, tr, "ло") forms["past_pl_short"] = combine(stem, tr, "ли") return forms end conjugations["3a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"23", "и", "+p", "7", "ё"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) -- make sure we can strip нуть from the stem and any translit; nom.strip_ending(stem, tr, "нуть") -- but then just strip the -уть and leave the н stem, tr = nom.strip_ending(stem, tr, "уть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "уть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "ущий", "-", "-", "увший", "увши", "ув") set_moving_ppp(forms, data) present_e_a(forms, stem, tr) append_imper_by_variant(forms, stem, tr, data.imper_variant, "3a") set_past(forms, stem .. "ул", tr and tr .. "ul", "", "а", "о", "и") return forms end local function guts_of_3b_3c(args, data, vclass) local forms = {} parse_variants(data, args[1], {"+p", "7", "ё"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) -- make sure we can strip нуть from the stem and any translit; nom.strip_ending(stem, tr, "ну́ть") -- but then just strip the -у́ть and leave the н stem, tr = nom.strip_ending(stem, tr, "у́ть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "у́ть") append_participles(forms, stem, tr, -- default is blank for pres passive and adverbial "у́щий", "-", "-", "у́вший", "у́вши", "у́в") set_moving_ppp(forms, data) append_imper(forms, stem, tr, "и́", "и́те") set_past(forms, stem, tr, "у́л", "у́ла", "у́ло", "у́ли") if data.conj_type == "3b" then present_e_b(forms, stem, tr) else stem, tr = com.make_ending_stressed(stem, tr) present_e_c(forms, stem, tr) end return forms end conjugations["3b"] = function(args, data) return guts_of_3b_3c(args, data) end conjugations["3c"] = function(args, data) return guts_of_3b_3c(args, data) end conjugations["4a"] = function(args, data) local forms = {} -- imperative variants, also щ, used for verbs like похитить (похи́щу) (4a), -- защитить (защищу́) (4b), поглотить (поглощу́) (4c) with a different -- iotation (т -> щ, not ч) parse_variants(data, args[1], {"23", "и", "щ", "past", "+p", "7", "жд"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = nom.strip_ending(stem, tr, "ить") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "ить") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") append_participles(forms, stem, tr, hushing and "ащий" or "ящий", "awkward-имый", hushing and "а" or "я", "ивший", "ивши", "ив") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "a", data.shch) append_imper_by_variant(forms, stem, tr, data.imper_variant, "4a") -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem .. "и", tr and tr .. "i", args, data) return forms end conjugations["4a1a"] = function(args, data) local forms = {} data.title = "4a // 1a" data.cat_conj_types = {"1a", "4a"} -- imperative variants, also щ, used for verbs like похитить (похи́щу) (4a), -- защитить (защищу́) (4b), поглотить (поглощу́) (4c) with a different -- iotation (т -> щ, not ч) parse_variants(data, args[1], {"23", "и", "щ", "past", "+p", "7", "жд"}) local stem4, tr4 = nom.split_russian_tr(get_stressed_arg(args, 2)) stem4, tr4 = nom.strip_ending(stem4, tr4, "ить") local hushing = rfind(stem4, "[шщжч]$") local stem1, tr1 if hushing then stem1 = stem4 .. "а" tr1 = tr4 and tr4 .. "a" else stem1 = stem4 .. "я" tr1 = tr4 and tr4 .. "ja" end no_stray_args(args, 2) forms["infinitive"] = combine(stem4, tr4, "ить") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. append_participles(forms, stem4, tr4, hushing and "ащий" or "ящий", "awkward-имый", hushing and "а" or "я", "ивший", "ивши", "ив") append_participles(forms, stem1, tr1, "ющий", "емый", "я", {}, {}, {}) set_class_4_ppp(forms, data, stem4, tr4) present_i(forms, stem4, tr4, "a", data.shch) present_je(forms, stem1, tr1, "a", data.shch) append_imper_by_variant(forms, stem4, tr4, data.imper_variant, "4a") append_imper(forms, stem1, tr1, "й", "йте") -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem4 .. "и", tr4 and tr4 .. "i", args, data) return forms end conjugations["4b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"щ", "past", "+p", "8", "жд"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = nom.strip_ending(stem, tr, "и́ть") no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "и́ть") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") append_participles(forms, stem, tr, hushing and "а́щий" or "я́щий", "awkward-и́мый", hushing and "а́" or "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "b", data.shch) append_imper(forms, stem, tr, "и́", "и́те") -- set prefix to "" as past stem may vary in length and no (1) variants local stem_noa, tr_noa = com.make_unstressed_once(stem, tr) set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "и́", tr_noa and tr_noa .. "i" .. AC, args, data) return forms end conjugations["4c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"щ", "4", "past", "+p", "7", "жд"}) local stem, tr = nom.split_russian_tr(get_stressed_arg(args, 2)) stem, tr = nom.strip_ending(stem, tr, "и́ть") stem, tr = com.make_ending_stressed(stem, tr) no_stray_args(args, 2) forms["infinitive"] = combine(stem, tr, "и́ть") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") local prap_end_stressed = hushing and "а́щий" or "я́щий" local prap_stem_stressed = hushing and "ащий" or "ящий" append_participles(forms, stem, tr, data.var4 == "req" and prap_stem_stressed or data.var4 == "opt" and {prap_end_stressed, prap_stem_stressed} or prap_end_stressed, "awkward-и́мый", hushing and "а́" or "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, stem, tr) present_i(forms, stem, tr, "c", data.shch) append_imper(forms, stem, tr, "и́", "и́те") local stem_noa, tr_noa = com.make_unstressed_once(stem, tr) set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "и́", tr_noa and tr_noa .. "i" .. AC, args, data) return forms end -- Combined class 5. But there's enough conditional code that it might make -- more sense to separate them again. local function guts_of_5(args, data) local forms = {} local is5a = data.conj_type == "5a" local is5b = data.conj_type == "5b" -- imperative ending (выгнать - выгони) and past stress; imperative is -- "й" after any vowel (e.g. выстоять), with or without an acute accent, -- otherwise ь or и if is5a or is5b then parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё"}) else parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё", "4"}) end local inf = get_stressed_arg(args, 2) local past_stem = nom.strip_ending(inf, nil, "ть") local stem = is5b and get_opt_unstressed_arg(args, 3) or get_opt_stressed_arg(args, 3) local default_stem = rmatch(past_stem, "^(.*)[еѣая]́?$") if not default_stem then error("Argument " .. inf .. " doesn't end in еть, ѣть, ать or ять") end if not is5a and not is5b then default_stem = com.make_ending_stressed(default_stem) end stem = stem or default_stem local pres_note = stem ~= default_stem and IRREG no_stray_args(args, 3) forms["infinitive"] = past_stem .. "ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(stem, "[шщжч]$") if is5a then append_participles_2stem(forms, stem, nil, past_stem, nil, hushing and "ащий" or "ящий", "имый", hushing and "а" or "я", "вший", "вши", "в", pres_note) elseif is5b then append_participles_2stem(forms, stem, nil, past_stem, nil, hushing and "а́щий" or "я́щий", "и́мый", hushing and "а́" or "я́", "вший", "вши", "в", pres_note) else -- var4 occurs with at least терпре́ть and дыша́ть local prap_end_stressed = hushing and "а́щий" or "я́щий" local prap_stem_stressed = hushing and "ащий" or "ящий" append_participles_2stem(forms, stem, nil, past_stem, nil, data.var4 == "req" and prap_stem_stressed or data.var4 == "opt" and {prap_end_stressed, prap_stem_stressed} or prap_end_stressed, "и́мый", hushing and "а́" or "я́", "вший", "вши", "в", pres_note) end set_moving_ppp(forms, data) present_i(forms, stem, nil, is5a and "a" or is5b and "b" or "c", nil, pres_note) append_imper_by_variant(forms, stem, nil, data.imper_variant, data.conj_type, pres_note) -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, past_stem, nil, args, data) return forms end conjugations["5a"] = function(args, data) return guts_of_5(args, data) end conjugations["5b"] = function(args, data) return guts_of_5(args, data) end conjugations["5c"] = function(args, data) return guts_of_5(args, data) end -- Implement 6a, 6°a, 6a1as13, 6a1as14, and 1a6a. local function guts_of_6a(args, data, vclass) local forms = {} -- Type 6a1a, section 13: -- Forms of both 6a and 1a can occur. They are the same in the infinitive -- and past. In the present active participle and the present/future, the -- type 6 forms are preferred and the type 1a forms are colloquial. In the -- remaining present forms and the imperative, both are equally preferred -- (we put the type-6 forms first because Zaliznyak lists them first). -- Type 6a1a section 14, type 1a6a: -- Forms of both 6a and 1a can occur. They are the same in the infinitive -- and past. In the present adverbial participle and the imperative, the -- type 1a forms are preferred and the type 6a forms are dated. In the -- remaining present forms, one or the other is slightly preferred (type -- 6a for 6a1a, type 1a for 1a6a). if vclass == "6a1as13" or vclass == "6a1as14" then data.title = "6a // 1a" data.cat_conj_types = {"1a", "6a"} elseif vclass == "1a6a" then data.title = "1a // 6a" data.cat_conj_types = {"1a", "6a"} end parse_variants(data, args[1], {"23", "и", "past", "+p", "7", "ё"}) local inf = get_stressed_arg(args, 2) local inf_past_stem = nom.strip_ending(inf, nil, "ть") local stem = rmatch(inf_past_stem, "^(.*)[ая]́?$") if not stem then error("Argument " .. inf .. " doesn't end in ать or ять") end if com.is_unstressed(stem) then -- колыха́ть, колеба́ть, etc. stem = com.make_ending_stressed(stem) end -- вызвать - вы́зову (в́ызов) local pres_stem = get_opt_stressed_arg(args, 3) or stem no_stray_args(args, 3) local pres_note = pres_stem ~= stem and IRREG -- no iotation, e.g. вырвать - вы́рву local no_iotation = vclass == "6°a" -- replace consonants for 1st person singular present/future local iotated_stem = no_iotation and pres_stem or com.iotation(pres_stem) forms["infinitive"] = inf_past_stem .. "ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") or no_iotation -- Participles -- pres_pasv_part is normal if infinitive ends in -ять, nonexistent except -- with certain lexical exceptions (колеба́ть, колыха́ть, глаго́лать, -- дви́гать with exceptional form дви́жимый) if infinitive ends in -ать local prpp_status = rfind(inf_past_stem, "я́?$") and "" or "none-" if vclass == "6a" or vclass == "6°a" or vclass == "6a1as13" then append_participles_2stem(forms, iotated_stem, nil, inf_past_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", hushing and "а" or "я", "вший", "вши", "в", pres_note) if vclass == "6a1as13" then -- then all the type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий*", prpp_status .. "емый", "я") end elseif vclass == "6a1as14" then -- first the preferred type 6a present active/passive participles append_participles(forms, iotated_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", {}, {}, {}, {}, pres_note) -- then all the type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий", "емый", "я", "вший", "вши", "в") -- then the dated type 6a present adverbial participle append_participles(forms, iotated_stem, nil, {}, {}, hushing and "а*" or "я*", {}, {}, {}, pres_note) else -- type 1a6a -- first the preferred type 1a forms (both are the same in the past) append_participles(forms, inf_past_stem, nil, "ющий", "емый", "я", "вший", "вши", "в") -- then the type 6a forms (dated in present adverbial participle) append_participles(forms, iotated_stem, nil, hushing and "ущий" or "ющий", prpp_status .. "емый", hushing and "а*" or "я*", {}, {}, {}, pres_note) end set_moving_ppp(forms, data) -- Present/future tense local function class_6_present() if no_iotation then present_e_a(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "a", nil, pres_note) end end if vclass == "6a" or vclass == "6°a" then class_6_present() elseif vclass == "1a6a" then -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a") class_6_present() elseif vclass == "6a1as14" then class_6_present() -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a") else -- 6a1as13 class_6_present() -- Do type 1a forms present_je(forms, inf_past_stem, nil, "a", nil, "*") end -- Imperative forms; if 1a6a or 6a1as14, type 6a forms are dated; -- if 6a1as13, type 6a forms go first. local function class_1_impr() append_imper(forms, inf_past_stem, nil, "й", "йте") end local function class_6_impr() local dated_note = ((vclass == "6a1as14" or vclass == "1a6a") and "*" or "") .. (pres_note or "") append_imper_by_variant(forms, iotated_stem, nil, data.imper_variant, "6a", dated_note) end if vclass == "6a1as14" or vclass == "1a6a" then class_1_impr() class_6_impr() elseif vclass == "6a1as13" then class_6_impr() class_1_impr() else class_6_impr() end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, inf_past_stem, nil, args, data) if vclass == "6a1as14" or vclass == "1a6a" then ut.insert_if_not(data.internal_notes, "* Dated.") elseif vclass == "6a1as13" then ut.insert_if_not(data.internal_notes, "* Colloquial; type-6 forms preferred.") end return forms end conjugations["6a"] = function(args, data) return guts_of_6a(args, data, "6a") end conjugations["6°a"] = function(args, data) return guts_of_6a(args, data, "6°a") end conjugations["6a1as13"] = function(args, data) return guts_of_6a(args, data, "6a1as13") end conjugations["6a1as14"] = function(args, data) return guts_of_6a(args, data, "6a1as14") end conjugations["1a6a"] = function(args, data) return guts_of_6a(args, data, "1a6a") end -- implement 6b, 6°b local function guts_of_6b(args, data, vclass) local forms = {} parse_variants(data, args[1], {"past", "+p", "7", "ё"}) local inf = get_stressed_arg(args, 2) local stem = rmatch(inf, "^(.*)[ая]́ть$") if not stem then error("Argument " .. inf .. " doesn't end in ать or ять") end -- звать - зов, драть - дер local pres_stem = get_opt_unstressed_arg(args, 3) or stem no_stray_args(args, 3) -- no iotation, e.g. рвать - рву local no_iotation = vclass == "6°b" local vowel_end_stem = is_vowel_stem(stem) local pres_note = pres_stem ~= stem and IRREG if no_iotation then present_e_b(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "b", nil, pres_note) end local impr_end = vowel_end_stem and "́й" -- accent on the preceding vowel or "и́" append_imper(forms, pres_stem, nil, impr_end, impr_end .. "те", pres_note) -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(pres_stem, "[шщжч]$") -- no pres_pasv_part local past_stem_with_vowel = stem .. (vowel_end_stem and "я́" or "а́") append_participles_2stem( forms, pres_stem, nil, past_stem_with_vowel, nil, ((hushing or no_iotation) and "у́щий" or "ю́щий"), {}, (hushing and "а́" or "я́"), "вший", "вши", "в", pres_note) forms["infinitive"] = combine(past_stem_with_vowel, nil, "ть") set_moving_ppp(forms, data) -- past_f for ждала́, подождала́ now handled through general mechanism --for разобрало́сь, past_n2 разобрало́ now handled through general mechanism --for разобрали́сь, past_pl2 разобрали́ now handled through general mechanism -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem .. (vowel_end_stem and "я́" or "а́"), nil, args, data) return forms end conjugations["6b"] = function(args, data) return guts_of_6b(args, data, "6b") end conjugations["6°b"] = function(args, data) return guts_of_6b(args, data, "6°b") end -- Implement 6c, 6°c and 6c1a. local function guts_of_6c(args, data, vclass) local forms = {} -- In type 6c1a, forms of both 6c and 1a can occur. They are -- the same in the infinitive and past. In the present active participle -- and the present/future, the type 6c forms are preferred and the type 1a -- forms are colloquial. In the remaining present forms and the imperative, -- both are equally preferred (we put the 6c forms first because Zaliznyak -- lists 6c first). if vclass == "6c1a" then data.title = "6c // 1a" data.cat_conj_types = {"1a", "6c"} end -- optional щ parameter for verbs like клеветать (клевещу́), past stress parse_variants(data, args[1], {"щ", "past", "+p", "7", "ё"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "а́ть") stem = com.make_ending_stressed(stem) -- разостла́ть - расстелю́, рассте́лешь local pres_stem = get_opt_stressed_arg(args, 3) or stem no_stray_args(args, 3) local pres_note = pres_stem ~= stem and IRREG -- remove accent for some forms local stem_noa = com.make_unstressed(stem) -- applies only to стона́ть, застона́ть, простона́ть local no_iotation = vclass == "6°c" -- iotate the stem local iotated_stem = no_iotation and pres_stem or com.iotation(pres_stem, nil, data.shch) local stem1a = stem_noa .. "а́" forms["infinitive"] = stem_noa .. "а́ть" -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") -- Participles append_participles_2stem(forms, iotated_stem, nil, stem_noa, nil, (hushing or no_iotation) and "ущий" or "ющий", {}, hushing and "а́" or "я́", "а́вший", "а́вши", "а́в", pres_note) if vclass == "6c1a" then -- then all the type 1a forms (both are the same in the past) append_participles(forms, stem1a, nil, "ющий*", "емый", "я") end set_moving_ppp(forms, data) if no_iotation then present_e_c(forms, pres_stem, nil, pres_note) else present_je(forms, pres_stem, nil, "c", data.shch, pres_note) end append_imper(forms, iotated_stem, nil, "и́", "и́те", pres_note) if vclass == "6c1a" then present_je(forms, stem1a, nil, "a", nil, "*") append_imper(forms, stem1a, nil, "й", "йте") end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem_noa .. "а́", nil, args, data) if vclass == "6c1a" then ut.insert_if_not(data.internal_notes, "* Colloquial; type-6 forms preferred.") end return forms end conjugations["6c"] = function(args, data) return guts_of_6c(args, data, "6c") end conjugations["6°c"] = function(args, data) return guts_of_6c(args, data, "6°c") end conjugations["6c1a"] = function(args, data) return guts_of_6c(args, data, "6c1a") end local function convert_last_e_to_yo(form) return rsub(form, "([еѣ])́?([^" .. com.vowel .. "]*)$", function(e, nonvowels) return (e == "е" and "ё" or "ѣ̈") .. nonvowels end) end local function guts_of_7(args, data, forms) local is7b = data.conj_type == "7b" local full_inf = get_stressed_arg(args, 2) local pres_stems = is7b and get_unstressed_arg(args, 3) or get_stressed_arg(args, 3) pres_stems = rsplit(pres_stems, ",") local past_stem if past_stem ~= "ёе" then past_stem = get_opt_stressed_arg(args, 4) end local past_stem_vowel_alt = past_stem == "ёе" if past_stem_vowel_alt then past_stem = nil end no_stray_args(args, 4) forms["infinitive"] = full_inf -- Construct the default past and present stem by a combination of -- infinitive and present final consonant. -- (1) Deduce the final consonant. local final_cons for _, pres_stem in ipairs(pres_stems) do -- Final cons is -ст if pres stem ends in vowel + ст, else -- single final cons [дтсзбп] (no actual examples of final п). -- Note that final -з can occur after a consonant (e.g. ползти́). local this_final_cons = rmatch(pres_stem, "[" .. com.vowel .. "]" .. AC .. "?(ст)$") if not this_final_cons then this_final_cons = rmatch(pres_stem, "([дтсзбп])$") end if not this_final_cons then error("Unable to determine final consonant from present stem " .. pres_stem) end if final_cons and this_final_cons ~= final_cons then error("Present stems with conflicting final consonants specified: " .. table.concat(pres_stems, ",")) end final_cons = this_final_cons end -- (2) Find the infinitive minus the termination. local prefix = rmatch(full_inf, "^(.*)[сз]т[иь]" .. AC .."?$") if not prefix then error("Strange infinitive " .. full_inf .. "in class 7") end -- (3) Combine infinitive with final consonant. local default_pres_stem = prefix .. final_cons if is7b then default_pres_stem = com.make_unstressed(default_pres_stem) end local default_past_stem = default_pres_stem if com.is_unstressed(default_past_stem) then default_past_stem = com.make_ending_stressed(default_past_stem) end -- (4) Past stems ending in -д and -т when the infinitive ends in -сть (but not -сти or -сти́) -- lose this consonant (page 85 of Zaliznyak, see also footnote 2 on that page). if rfind(full_inf, "сть$") then default_past_stem = rsub(default_past_stem, "[дт]$", "") end -- (5) If 7b and the past stem wasn't originally specified as ёе, the past stem gets -- ё in place of е. if is7b and not past_stem_vowel_alt then default_past_stem = convert_last_e_to_yo(default_past_stem) end for _, pres_stem in ipairs(pres_stems) do local pres_note = pres_stem ~= default_pres_stem and IRREG if is7b then present_e_b(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и́", "и́те", pres_note) else present_e_a(forms, pres_stem, nil, pres_note) append_imper_by_variant(forms, pres_stem, nil, data.imper_variant, "7a", pres_note) end end -- Construct the past stem if not specified. Note that we then derive a separate -- past-tense stem from this stem, and this stem as such ends up applying only -- to the past active and adverbial participles. if not past_stem then past_stem = default_past_stem end local past_note = past_stem ~= default_past_stem and IRREG -- Derive the past tense stem from the past stem derived above. This has ё instead of е -- in 7b verbs; it also loses д and т in all cases, when the past stem derived above only loses -- these consonants in some cases. local past_tense_stem = past_stem if is7b then past_tense_stem = convert_last_e_to_yo(past_tense_stem) end past_tense_stem = rsub(past_tense_stem, "[дт]$", "") local vowel_pp = is_vowel_stem(past_stem) local pap = vowel_pp and "вши" or "ши" local var9_note_symbol = next_note_symbol(data) for _, pres_stem in ipairs(pres_stems) do append_participles_2stem(forms, pres_stem, nil, past_stem, nil, is7b and "у́щий" or "ущий", "-", is7b and "я́" or "я", vowel_pp and "вший" or "ший", data.var9 and {is7b and "я́" or "я", pap .. var9_note_symbol} or pap, vowel_pp and not data.var9 and "в" or "-", pres_note, past_note) end if data.var9 then ut.insert_if_not(data.internal_notes, var9_note_symbol .. " Dated.") end -- set prefix to "" as past stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, past_tense_stem, nil, args, data, -- 0 ending if the past stem ends in a consonant not is_vowel_stem(past_tense_stem) and "no-pastml", past_note) -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) end conjugations["7a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"23", "и", "9","past", "+p"}) -- лезть - ле́зши - non-existent past_actv_part handled through general mechanism guts_of_7(args, data, forms) return forms end conjugations["7b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"9", "past", "+p"}) guts_of_7(args, data, forms) return forms end local function class_8a_stem_to_infinitive(stem) -- map e.g. вы́сек back to высе́чь return rsub(stem, "[гк]$", "чь") end local function class_8b_stem_to_infinitive(stem) -- map e.g. отвлёк back to отвле́чь -- map e.g. зажёг back to заже́чь return com.make_ending_stressed(rsub(rsub(rsub(stem, "ё", "е"), "ѣ̈", "ѣ"), "[гк]$", "чь")) end conjugations["8a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local full_inf = get_stressed_arg(args, 2) local stem = get_stressed_arg(args, 3) local stressed_past_stem = get_opt_stressed_arg(args, 4) or stem no_stray_args(args, 4) forms["infinitive"] = full_inf local pres_note = class_8a_stem_to_infinitive(stem) ~= full_inf and IRREG local stressed_past_note = class_8a_stem_to_infinitive(stressed_past_stem) ~= full_inf and IRREG -- default for pres_pasv_part is blank append_participles_2stem(forms, stem, nil, stressed_past_stem, nil, "ущий", "-", "-", "ший", "ши", "-", pres_note, stressed_past_note) local iotated_stem = com.iotation(stem) append_pres_futr(forms, iotated_stem, nil, {}, "ешь", "ет", "ем", "ете", {}, pres_note) append_pres_futr(forms, stem, nil, "у", {}, {}, {}, {}, "ут", pres_note) append_imper(forms, stem, nil, "и", "ите", pres_note) -- set prefix to "" as stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, stem, nil, args, data, "no-pastml", pres_note) forms["past_m"] = stressed_past_stem .. (stressed_past_note or "") -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) return forms end conjugations["8b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local full_inf = get_stressed_arg(args, 2) local stem = get_unstressed_arg(args, 3) local stressed_past_stems = rsplit(args[4] or "ё", ",") for _, stressed_past_stem in ipairs(stressed_past_stems) do if stressed_past_stem ~= "е" then check_stressed_arg(stressed_past_stem, 4) end end no_stray_args(args, 4) forms["infinitive"] = full_inf local pres_note = class_8b_stem_to_infinitive(stem) ~= full_inf and IRREG local iotated_stem = com.iotation(stem) append_pres_futr(forms, iotated_stem, nil, {}, "ёшь", "ёт", "ём", "ёте", {}, pres_note) append_pres_futr(forms, stem, nil, "у́", {}, {}, {}, {}, "у́т", pres_note) append_imper(forms, stem, nil, "и́", "и́те", pres_note) -- set prefix to "" as stem may vary in length and no (1) variants set_past_by_stress(forms, data.past_stress, "", nil, com.make_ending_stressed(stem), nil, args, data, "no-pastml", pres_note) forms["past_m"] = nil for _, stressed_past_stem in ipairs(stressed_past_stems) do local pastm_stem, past_part_stem if stressed_past_stem == "е" then past_part_stem = com.make_ending_stressed(stem) pastm_stem = past_part_stem elseif stressed_past_stem == "ё" then past_part_stem = convert_last_e_to_yo(com.make_ending_stressed(stem)) pastm_stem = past_part_stem elseif stressed_past_stem == "ёе" then past_part_stem = com.make_ending_stressed(stem) pastm_stem = convert_last_e_to_yo(past_part_stem) else pastm_stem = stressed_past_stem past_part_stem = stressed_past_stem end local past_note = class_8b_stem_to_infinitive(pastm_stem) ~= full_inf and IRREG -- default for pres_pasv_part is blank; влечь -> влеко́мый handled through -- general override mechanism append_participles_2stem(forms, stem, nil, past_part_stem, nil, "у́щий", "-", "-", "ший", "ши", "-", pres_note, past_note) append_form(forms, "past_m", pastm_stem, nil, "", past_note) end -- set PPP; must be done after both present 3sg and past fem have been set set_class_7_8_ppp(forms, args, data) return forms end conjugations["9a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "еть") local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) local default_pres_stem = prefix .. rsub(base, "е", "") pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem .. "еть" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "ший", "ши", "ев") present_e_a(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и", "ите", pres_note) -- past_m doesn't end in л set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data, "no-pastml") set_ppp_from_past_m(forms, args, data) return forms end conjugations["9b"] = function(args, data) local forms = {} --for this type, it's important to distinguish impf and pf local impf = rfind(data.verb_type, "^impf") parse_variants(data, args[1], {"past", "+p", "*"}) local stem_noa = nom.strip_ending(get_stressed_arg(args, 2), nil, "е́ть") local stem = rsub(stem_noa, "(.*)е", "%1ё") local pres_stem = get_opt_unstressed_arg(args, 3) -- stem used for past active and adverbial participles; defaults to past_m local past_part_stem = get_opt_stressed_arg(args, 4) no_stray_args(args, 4) local prefix, _, base, _ = split_monosyllabic_main_verb(stem, nil, "single_cons_base") local default_pres_stem = data.star and construct_long_prefix_variant(prefix) .. rsub(base, "[её]", "") or prefix .. rsub(base, "[её]", "") pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem_noa .. "е́ть" present_e_b(forms, pres_stem, nil, pres_note) append_imper(forms, pres_stem, nil, "и́", "и́те", pres_note) -- past_m doesn't end in л set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data, "no-pastml") set_ppp_from_past_m(forms, args, data) append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", {}, {}, -- impf: тереть -> тёрши -- pf: растереть -> растёрши, растере́в -- we handle (рас)тёрши down below because the stress depends on the -- past_m: запереть -> за́пер, за́перши(й) {}, {}, impf and {} or "е́в", pres_note) if past_part_stem then for _, ppstem in ipairs(rsplit(past_part_stem, ",")) do append_participles(forms, ppstem, nil, {}, {}, {}, "ший", "ши", {}) end else iterate_over_prop(forms, args, "past_m", function(ru, tr, note) append_participles(forms, ru, tr, {}, {}, {}, "ший", "ши", {}, note) end) end return forms end conjugations["10a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "оть") no_stray_args(args, 2) forms["infinitive"] = stem .. "оть" -- These verbs are perfective-only, no present participles append_participles(forms, stem, nil, "-", "-", "-", "овший", "овши", "ов") set_moving_ppp(forms, data) present_je(forms, stem, nil, "a") append_imper(forms, stem, nil, "и", "ите") set_past(forms, stem .. "ол", nil, "", "а", "о", "и") return forms end conjugations["10c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p", "7"}) local inf_stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") -- present tense stressed stem "моло́ть" - ме́лет local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = com.make_ending_stressed(nom.strip_ending(inf_stem, nil, "о́")) pres_stem = pres_stem or default_pres_stem -- remove accent for some forms local pres_stem_noa = com.remove_accents(pres_stem) local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = inf_stem .. "ть" -- default for pres_pasv_part is blank append_participles_2stem(forms, pres_stem, nil, inf_stem, nil, "ющий", "-", "я́", "вший", "вши", "в", pres_note) set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "c", nil, pres_note) append_imper(forms, pres_stem_noa, nil, "и́", "и́те", pres_note) set_past(forms, inf_stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["11a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ить") no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem .. "и") forms["infinitive"] = stem .. "ить" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "ивший", "ивши", "ив") present_je(forms, stem .. "ь", nil, "a") append_imper(forms, stem .. "ей", nil, "", "те") set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["11b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p", "*"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "и́ть") local pres_stem = get_opt_unstressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem .. "и́", nil, "single_cons_base") local default_pres_stem = data.star and construct_long_prefix_variant(prefix) .. rsub(base, "и́$", "") or stem pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG forms["infinitive"] = stem .. "и́ть" append_participles_2stem(forms, pres_stem, nil, stem, nil, "ью́щий", "-", "ья́", "и́вший", "и́вши", "и́в", pres_note) present_je(forms, pres_stem .. "ь", nil, "b", nil, pres_note) append_imper(forms, stem .. "е́й", nil, "", "те") -- e.g. пила́, лила́ set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["12a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_opt_stressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = stem pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" append_participles_2stem(forms, pres_stem, nil, stem, nil, "ющий", "емый", "я", "вший", "вши", "в", pres_note) present_je(forms, pres_stem, nil, "a", nil, pres_note) append_imper(forms, pres_stem .. "й", nil, "", "те", pres_note) set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["12b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_opt_unstressed_arg(args, 3) no_stray_args(args, 3) local default_pres_stem = com.make_unstressed_once(stem) pres_stem = pres_stem or default_pres_stem local pres_note = pres_stem ~= default_pres_stem and IRREG local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "ю́щий", "-", "я́", "вший", "вши", "в", pres_note) present_je(forms, pres_stem, nil, "b", nil, pres_note) -- the preceding vowel is stressed append_imper(forms, pres_stem .. "́й", nil, "", "те", pres_note) -- e.g. гнила́ but пе́ла set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["13b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = nom.strip_ending(stem, nil, "ва́") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- tricky to use append_participles_2stem() because only pres_actv_part -- uses pres_stem, not all present participles forms["pres_actv_part"] = pres_stem .. "ю́щий" forms["pres_pasv_part"] = stem .. "емый" forms["pres_adv_part"] = stem .. "я" forms["past_actv_part"] = stem .. "вший" forms["past_adv_part"] = stem .. "вши" forms["past_adv_part_short"] = stem .. "в" set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "b") forms["impr_sg"] = stem .. "й" forms["impr_pl"] = stem .. "йте" set_past(forms, stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["14a"] = function(args, data) -- only one verb: вы́жать local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_stressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- perfective only append_participles(forms, stem, nil, "-", "-", "-", "вший", "вши", "в") present_e_a(forms, pres_stem) forms["impr_sg"] = pres_stem .. "и" forms["impr_pl"] = pres_stem .. "ите" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["14b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_unstressed_arg(args, 3) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_b(forms, pres_stem) forms["impr_sg"] = pres_stem .. "и́" forms["impr_pl"] = pres_stem .. "и́те" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["14c"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local pres_stem = get_stressed_arg(args, 3) local pres_stem_noa = com.make_unstressed(pres_stem) no_stray_args(args, 3) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, stem, nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_c(forms, pres_stem) forms["impr_sg"] = pres_stem_noa .. "и́" forms["impr_pl"] = pres_stem_noa .. "и́те" --two forms for past_m: при́нялся, приня́лся --изъя́ла but приняла́ set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["15a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, stem, nil, "нущий", "-", "-", "вший", "вши", "в") present_e_a(forms, stem .. "н") forms["impr_sg"] = stem .. "нь" forms["impr_pl"] = stem .. "ньте" set_past(forms, stem .. "л", nil, "", "а", "о", "и") set_ppp_from_past_m(forms, args, data) return forms end conjugations["16a"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, stem, nil, "ву́щий", "-", "-", "вший", "вши", "в") present_e_a(forms, stem .. "в") forms["impr_sg"] = stem .. "ви" forms["impr_pl"] = stem .. "вите" set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["16b"] = function(args, data) local forms = {} parse_variants(data, args[1], {"past", "+p"}) local stem = nom.strip_ending(get_stressed_arg(args, 2), nil, "ть") local stem_noa = com.make_unstressed(stem) no_stray_args(args, 2) local prefix, _, base, _ = split_monosyllabic_main_verb(stem) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part append_participles(forms, stem, nil, "ву́щий", "-", "вя́", "вший", "вши", "в") present_e_b(forms, stem_noa .. "в") forms["impr_sg"] = stem_noa .. "ви́" forms["impr_pl"] = stem_noa .. "ви́те" -- e.g. прижило́сь, прижи́лось set_past_by_stress(forms, data.past_stress, prefix, nil, base, nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg"] = function(args, data) local prefix, _, main = split_known_main_verb(get_stressed_arg(args, 2), -- честь must go before есть {"бежа́ть", "бѣжа́ть", "хоте́ть", "хотѣ́ть", "да́ть", "че́сть", "е́сть", "ѣ́сть", "сы́пать", "лга́ть", "мо́чь", "идти́", "йти́", "е́хать", "ѣ́хать", "мину́ть", "живописа́ть", "ле́чь", "зи́ждить", "зы́бить", "кля́сть", "стели́ть", "бы́ть", "сса́ть", "сца́ть", "чти́ть", "шиби́ть", "реве́ть", "има́ть", "вня́ть", "обя́зывать"}) main = com.make_unstressed_once(main) if not conjugations["irreg-" .. main] then error("Strange, can't find conjugation for main verb " .. main) end return conjugations["irreg-" .. main](args, data) end conjugations["irreg-бежать"] = function(args, data) -- irregular, only for verbs derived from бежать with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"бежа́ть", "бѣжа́ть"}) data.title = com.is_stressed(prefix) and "5a" or "5b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "бежа́ть" append_participles_2stem(forms, "бег", nil, "бежа́", nil, "у́щий", "-", "-", "вший", "вши", "в", IRREG) append_imper(forms, "беги́", nil, "", "те", IRREG) append_pres_futr(forms, "бе", nil, "гу́" .. IRREG, "жи́шь", "жи́т", "жи́м", "жи́те", "гу́т" .. IRREG) set_past(forms, "бежа́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^бе", "бѣ") end prepend_prefix(forms, prefix) -- no PPP's for any derivatives of бежать return forms end conjugations["irreg-бѣжать"] = conjugations["irreg-бежать"] conjugations["irreg-хотеть"] = function(args, data) -- irregular, only for verbs derived from хотеть with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"хоте́ть", "хотѣ́ть"}) data.title = "5c'" data.cat_conj_types = {"5c"} -- no class for 5c', no point in creating for just this verb -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "хоте́ть" append_participles_2stem(forms, "хот", nil, "хоте́", nil, "я́щий", "-", "я́", "вший", "вши", "в") append_imper(forms, "хоти́", nil, "", "те") append_pres_futr(forms, "", nil, "хочу́", "хо́чешь" .. IRREG, "хо́чет" .. IRREG, "хоти́м", "хоти́те", "хотя́т") set_past(forms, "хоте́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^хоте", "хотѣ") end prepend_prefix(forms, prefix) return forms end conjugations["irreg-хотѣть"] = conjugations["irreg-хотеть"] conjugations["irreg-дать"] = function(args, data) -- irregular, only for verbs derived from дать with the same stress pattern and вы́дать local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "да́ть") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "да́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "", nil, "даю́щий", "-", "-", "да́вший", "да́вши", "да́в") append_imper(forms, "да́й", nil, "", "те") append_pres_futr(forms, "", nil, "да́м", "да́шь", "да́ст", "дади́м", "дади́те", "даду́т") prepend_prefix(forms, prefix) set_past_by_stress(forms, data.past_stress, prefix, nil, "да́", nil, args, data) if data.ppp then if prefix == "пере" then set_ppp(forms, "", nil, "пе́реданный") elseif prefix == "раз" then set_ppp(forms, "", nil, "ро́зданный") else set_moving_ppp(forms, data) end end return forms end conjugations["irreg-есть"] = function(args, data) -- irregular, only for verbs derived from есть local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"е́сть", "ѣ́сть"}) data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "е́сть" append_participles_2stem(forms, "ед", nil, "е́", nil, "я́щий", "о́мый", "я́", "вший", "вши", "в") if data.ppp then set_ppp(forms, "е́д", nil, "енный") end append_imper(forms, "е́шь", nil, "", "те") append_pres_futr(forms, "е́", nil, "м", "шь", "ст", "ди́м", "ди́те", "дя́т") set_past(forms, "е́л", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^е", "ѣ") end prepend_prefix(forms, prefix) return forms end conjugations["irreg-ѣсть"] = conjugations["irreg-есть"] conjugations["irreg-сыпать"] = function(args, data) -- irregular, only for verbs derived from сыпать local forms = {} --for this type, it's important to distinguish if it's reflexive for вы́сыпаться vs. вы́сыпать imperative local prefix = split_known_main_verb(get_stressed_arg(args, 2), "сы́пать") data.title = "6a" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "сы́пать" append_participles(forms, "сы́п", nil, "лющий", "лемый", {"ля", "я" .. IRREG}, "авший", "авши", "ав") append_imper(forms, "сы́п", nil, -- вы́сыпать (but not вы́сыпаться) has two imperative singulars com.is_stressed(prefix) and not data.refl and {"и", "ь"} or "ь", "ьте", IRREG) present_je(forms, "сы́пл", nil, "a") append_pres_futr(forms, "сы́п", nil, {}, "ешь", "ет", "ем", "ете", {}, IRREG) set_past(forms, "сы́пал", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-лгать"] = function(args, data) -- irregular, only for verbs derived from лгать with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "лга́ть") data.title = "6°b/c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "лга́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "лг", nil, "у́щий", "-", "-", "а́вший", "а́вши", "а́в") append_imper(forms, "лги́", nil, "", "те") append_pres_futr(forms, "", nil, "лгу́", "лжёшь" .. IRREG, "лжёт" .. IRREG, "лжём" .. IRREG, "лжёте" .. IRREG, "лгу́т") set_past(forms, "лга́л", nil, "", "а́", "о", "и") prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-мочь"] = function(args, data) -- irregular, only for verbs derived from мочь with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "мо́чь") data.title = "8c/b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "мо́чь" -- no passive or adverbial participles append_participles(forms, "мо́г", nil, "у́щий", "-", "-", "ший", "-", "-") append_imper(forms, "моги́", nil, "", "те") append_pres_futr(forms, "", nil, "могу́", "мо́жешь", "мо́жет", "мо́жем", "мо́жете", "мо́гут") set_past(forms, "мо́г", nil, "", "ла́", "ло́", "ли́") prepend_prefix(forms, prefix) return forms end conjugations["irreg-идти"] = function(args, data) -- irregular, only for verbs derived from идти, including прийти́ and в́ыйти local forms = {} local prefix = args[2] == "идти́" and "" or split_known_main_verb(get_stressed_arg(args, 2), "йти́") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b/b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no pres_pasv_part if prefix == "" then -- only идти, present imperfective forms["infinitive"] = "идти́" append_imper(forms, "иди́", nil, "", "те") present_e_b(forms, "ид") -- no past_adv_part_short append_participles(forms, "", nil, "иду́щий", "-", "идя́", "ше́дший", "ше́дши", "-") elseif rfind(prefix, "и$") then -- при forms["infinitive"] = "йти́" append_imper(forms, "ди́", nil, "", "те") present_e_b(forms, "д") append_participles(forms, "", nil, "-", "-", "-", "ше́дший", "ше́дши", "дя́") else forms["infinitive"] = "йти́" append_imper(forms, "йди́", nil, "", "те") present_e_b(forms, "йд") append_participles(forms, "", nil, "-", "-", "-", "ше́дший", "ше́дши", "йдя́") end set_past(forms, "", nil, "шёл", "шла́", "шло́", "шли́") prepend_prefix(forms, prefix) if data.ppp then if prefix == "на" or prefix == "про" then -- найти́ and пройти́ exceptionally have the stress on the prefix set_ppp(forms, prefix, nil, "́йденный") else -- вы́йти and прийти́ are intransitive so we don't have to worry about them set_ppp(forms, prefix, nil, "йдённый") end end return forms end conjugations["irreg-йти"] = conjugations["irreg-идти"] conjugations["irreg-ехать"] = function(args, data) -- irregular, only for verbs derived from ехать local forms = {} local old = data.old local prefix = split_known_main_verb(get_stressed_arg(args, 2), {"е́хать", "ѣ́хать"}) data.title = "irreg-a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "е́хать" -- no pres_pasv_part -- no pres_adv_part append_participles_2stem(forms, "е́д", nil, "е́х", nil, "ущий", "-", "-", "авший", "авши", "ав") present_e_a(forms, "е́д") set_past(forms, "е́хал", nil, "", "а", "о", "и") if data.old then rsub_forms(forms, "^е", "ѣ") end prepend_prefix(forms, prefix) --special-case the imperative --literary (special) imperative forms for ехать are поезжа́й, поезжа́йте impstem = data.old and "ѣзжа́й" or "езжа́й" if prefix == "" then append_imper(forms, "по" .. impstem, nil, "", "те") append_imper(forms, impstem, nil, "", "те") elseif com.is_stressed(prefix) then append_imper(forms, com.make_unstressed_once(prefix) .. impstem, nil, "", "те") else append_imper(forms, prefix .. impstem, nil, "", "те") end return forms end conjugations["irreg-ѣхать"] = conjugations["irreg-ехать"] conjugations["irreg-минуть"] = function(args, data) -- for the irregular verb "мину́ть" local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "мину́ть") data.title = "3c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "мину́ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, "ми́н", nil, "у́щий", "-", "-", "у́вший", "у́вши", "у́в") present_e_c(forms, "ми́н") forms["pres_futr_1sg"] = "-" -- no futr 1sg -- no imperative -- two possible variants, one with root-only stress, the other with -- either root or suffix stress. if not args["root_past_stress"] then append_past(forms, "мину́л", nil, "", "а", "о", "и") end append_past(forms, "ми́нул", nil, "", "а", "о", "и", IRREG) prepend_prefix(forms, prefix) set_moving_ppp(forms, data) return forms end conjugations["irreg-живописать"] = function(args, data) -- for irregular verb "живописа́ть", mixture of types 1 and 2 local forms = {} local inf = get_stressed_arg(args, 2) data.title = "1a" parse_variants(data, args[1], {"+p"}) local inf_stem = nom.strip_ending(inf, nil, "ть") local pres_stem = rfind(inf_stem, "а́$") and rsub(inf_stem, "а́$", "у́") or error("Unexpected infinitive " .. inf) no_stray_args(args, 2) forms["infinitive"] = inf_stem .. "ть" -- no pres_pasv_part append_participles_2stem(forms, pres_stem, nil, inf_stem, nil, "ющий", "-", "я", "вший", "вши", "в", IRREG) set_moving_ppp(forms, data) present_je(forms, pres_stem, nil, "a", nil, IRREG) append_imper(forms, pres_stem .. "й", nil, "", "те", IRREG) set_past(forms, inf_stem .. "л", nil, "", "а", "о", "и") return forms end conjugations["irreg-лечь"] = function(args, data) -- irregular, only for verbs derived from лечь with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "ле́чь") data.title = "8a/b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "ле́чь" -- no pres parts because always perfective -- no past_adv_part_short append_participles(forms, "лёг", nil, "-", "-", "-", "ший", "ши", "-") append_imper(forms, "ля́г", nil, "", "те", IRREG) append_pres_futr(forms, "ля́", nil, "гу", "жешь", "жет", "жем", "жете", "гут", IRREG) set_past(forms, "", nil, "лёг", "легла́", "легло́", "легли́") prepend_prefix(forms, prefix) return forms end conjugations["irreg-честь"] = function(args, data) -- irregular, only for verbs derived from идти, including прийти́ and в́ыйти local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "че́сть") local pre_two_cons_prefix = prefix == "об" and "обо" or prefix == "с" and "со" or prefix == "рас" and "разо" or prefix data.title = prefix == "" and "7b/b" or com.is_stressed(prefix) and "7a⑨" or pre_two_cons_prefix ~= prefix and "7*b/b⑨" or "7b/b⑨" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no pres_pasv_part forms["infinitive"] = "че́сть" append_imper(forms, "чти́", nil, "", "те", IRREG) present_e_b(forms, "чт", nil, IRREG) if prefix == "" then append_participles(forms, "", nil, "чту́щий", "-", "чтя́", "чти́вший", "чти́вши", "чти́в", IRREG) elseif com.is_stressed(prefix) then append_participles(forms, "", nil, "-", "-", "-", "-", "чтя́", "-", IRREG) else append_participles(forms, "", nil, "-", "-", "-", "-", {"чтя́" .. IRREG, "чётши*"}, "-") ut.insert_if_not(data.internal_notes, "* Dated.") end if data.ppp then set_ppp(forms, "", nil, "чтённый" .. IRREG) end set_past(forms, "", nil, "чёл", "чла́" .. IRREG, "чло́" .. IRREG, "чли́" .. IRREG) prepend_prefix(forms, prefix, pre_two_cons_prefix) return forms end conjugations["irreg-зиждить"] = function(args, data) -- irregular, only for verbs derived from зиждить(ся) with the same stress pattern local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "зи́ждить") data.title = "irreg-a" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "зи́ждить" append_participles(forms, "зи́жд", nil, "ущий", "емый", "я", "ивший", "ивши", "ив") if data.ppp then set_ppp(forms, "зи́жд", nil, "енный") end append_imper(forms, "зи́жди", nil, "", "те") present_e_a(forms, "зи́жд") set_past(forms, "зи́ждил", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-зыбить"] = function(args, data) -- irregular, only for verbs derived from зыбить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "зы́бить") data.title = "irreg-a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "зы́бить" append_participles(forms, "зы́б", nil, "лющий", "лемый", "ля", "ивший", "ивши", "ив") append_imper(forms, "зы́бли", nil, "", "те") present_je(forms, "зы́б", nil, "a") set_past(forms, "зы́бил", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-клясть"] = function(args, data) -- irregular, only for verbs derived from клясть with the same stress pattern local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "кля́сть") data.title = "irreg-b" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "кля́сть" append_participles_2stem(forms, "клян", nil, "кля́", nil, "у́щий", "и́мый", "я́", "вший", "вши", "в") append_imper(forms, "кляни́", nil, "", "те") present_e_b(forms, "клян") prepend_prefix(forms, prefix) set_past_by_stress(forms, data.past_stress, prefix, nil, "кля́", nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg-стелить"] = function(args, data) -- irregular, only for verbs derived from стелить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "стели́ть") data.title = com.is_stressed(prefix) and "4a" or "4c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "стели́ть" append_participles(forms, "сте́л", nil, "ющий" .. IRREG, "и́мый", "я́", "и́вший", "и́вши", "и́в") set_class_4_ppp(forms, data, "сте́л", nil, data.title) append_imper(forms, "стели́", nil, "", "те") append_pres_futr(forms, "сте́л", nil, "ю́", {}, {}, {}, {}, {}) append_pres_futr(forms, "сте́л", nil, {}, "ешь", "ет", "ем", "ете", "ют", IRREG) set_past(forms, "стели́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-быть"] = function(args, data) -- irregular, only for verbs derived from быть with various stress patterns, the actual verb быть different from its derivatives local forms = {} --for this type, it's important to distinguish if it's reflexive to set some stress patterns local prefix = split_known_main_verb(get_stressed_arg(args, 2), "бы́ть") data.title = "irreg-a" parse_variants(data, args[1], {"past", "+p"}) no_stray_args(args, 2) forms["infinitive"] = "бы́ть" -- no pres_pasv_part append_participles(forms, "", nil, "су́щий", "-", "бу́дучи", "бы́вший", "бы́вши", "бы́в") append_imper(forms, "бу́дь", nil, "", "те") prepend_prefix(forms, prefix) -- only for "бы́ть", some forms are archaic if forms["infinitive"] == "бы́ть" then append_pres_futr(forms, "", nil, "есть", "есть", "есть", "есть", "есть", "есть") elseif com.is_stressed(prefix) then -- if the prefix is stressed, e.g. "вы́быть" present_e_a(forms, prefix .. "буд") else present_e_a(forms, prefix .. "бу́д") end set_past_by_stress(forms, data.past_stress, prefix, nil, "бы́", nil, args, data) set_ppp_from_past_m(forms, args, data) return forms end conjugations["irreg-ссать-сцать"] = function(args, data) -- irregular, only for verbs derived from ссать and сцать (both vulgar!) local forms = {} local prefix, _, stem = split_known_main_verb(get_stressed_arg(args, 2), {"сса́ть", "сца́ть"}) data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) stem = nom.strip_ending(stem, nil, "ть") local pres_stem = rsub(stem, "а́?$", "") no_stray_args(args, 2) forms["infinitive"] = stem .. "ть" -- no pres_pasv_part -- no pres_adv_part append_participles(forms, pres_stem, nil, "у́щий", "-", "-", "а́вший", "а́вши", "а́в") append_imper(forms, pres_stem, nil, "ы́", "ы́те") append_pres_futr(forms, pres_stem, nil, "у́", "ы́шь", "ы́т", "ы́м", "ы́те", "у́т") set_past(forms, stem .. "л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-ссать"] = conjugations["irreg-ссать-сцать"] conjugations["irreg-сцать"] = conjugations["irreg-ссать-сцать"] conjugations["irreg-чтить"] = function(args, data) -- irregular, only for verbs derived from чтить local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "чти́ть") data.title = "4b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "чти́ть" append_participles_2stem(forms, "чт", nil, "чти́", nil, {"я́щий", "у́щий" .. IRREG}, "и́мый", "я́", "вший", "вши", "в") if data.ppp then set_ppp(forms, "чт", nil, "ённый") end append_imper(forms, "чти́", nil, "", "те") append_pres_futr(forms, "чт", nil, "у́" .. IRREG, "и́шь", "и́т", "и́м", "и́те", {"я́т", "у́т" .. IRREG}) set_past(forms, "чти́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-шибить"] = function(args, data) -- irregular, only for verbs in -шибить(ся) local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "шиби́ть") data.title = com.is_stressed(prefix) and "irreg-a" or "irreg-b" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) -- no present participles forms["infinitive"] = "шиби́ть" append_participles(forms, "шиби́", nil, "-", "-", "-", "вший", "вши", "в") if data.ppp then set_ppp(forms, "ши́бл", nil, "енный") end append_imper(forms, "шиби́", nil, "", "те") present_e_b(forms, "шиб") set_past(forms, "ши́б", nil, "", "ла", "ло", "ли") prepend_prefix(forms, prefix) return forms end conjugations["irreg-реветь"] = function(args, data) -- irregular, only for verbs derived from "реветь" local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "реве́ть") data.title = "irreg-b" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "реве́ть" -- no pres_pasv_part append_participles_2stem(forms, "рев", nil, "реве́", nil, "у́щий", "-", "я́", "вший", "вши", "в") present_e_b(forms, "рев") append_imper(forms, "реви́", nil, "", "те") set_past(forms, "реве́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-имать"] = function(args, data) -- irregular, only for внимать and certain archaic verbs (e.g. имать as -- conjugated in the 18th century, отъимать) local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "има́ть") data.title = "1a // 6a" data.cat_conj_types = {"1a", "6a"} parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "има́ть" -- handle внемл- forms append_participles(forms, "е́мл", nil, "ющий", "емый", {"я", "я́"}, {}, {}, {}) -- handle внима́- forms append_participles(forms, "има́", nil, "ющий", "емый", "я", "вший", "вши", "в") if data.ppp then -- FIXME, do class-1a-type ppp's (e.g. вни́манный) exist? -- ruwikt marks them with a * set_ppp(forms, "е́мл", nil, "енный") end append_imper(forms, "", nil, {"е́мли", "емли́", "има́й"}, {"е́млите", "емли́те", "има́йте"}) present_je(forms, "е́мл", nil, "a") -- Both вне́млю and внемлю́ are possible append_pres_futr(forms, "емл", nil, "ю́", {}, {}, {}, {}, {}) present_je(forms, "има́", nil, "a") set_past(forms, "има́л", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end conjugations["irreg-внять"] = function(args, data) -- irregular, only for внять local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "вня́ть") data.title = "14c/c" parse_variants(data, args[1], {"+p"}) no_stray_args(args, 2) forms["infinitive"] = "вня́ть" -- perfective only; no present participles append_participles(forms, "вня́", nil, "-", "-", "-", "вший", "вши", "в") append_imper(forms, "вними́", nil, "", "те") append_imper(forms, "вонми́", nil, "", "те") present_e_c(forms, "вни́м") present_e_c(forms, "во́нм") set_past(forms, "вня́л", nil, "", "а́", "о", "и") set_ppp_from_past_m(forms, args, data) prepend_prefix(forms, prefix) return forms end conjugations["irreg-обязывать"] = function(args, data) -- irregular, only for обязывать and обязываться local forms = {} local prefix = split_known_main_verb(get_stressed_arg(args, 2), "обя́зывать") data.title = "1a" -- no past passive participles of any verbs of this type parse_variants(data, args[1], {}) no_stray_args(args, 2) forms["infinitive"] = "обя́зывать" append_participles_2stem(forms, "обя́з", nil, "обя́зыва", nil, {"ывающий", "у́ющий"}, {"ываемый", "у́емый"}, {"ывая", "у́я"}, "вший", "вши", "в") append_imper(forms, "обя́зывай", nil, "", "те") append_imper(forms, "обязу́й", nil, "", "те") present_je(forms, "обя́зыва", nil, "a") present_je(forms, "обязу́", nil, "a") set_past(forms, "обя́зывал", nil, "", "а", "о", "и") prepend_prefix(forms, prefix) return forms end --[=[ Partial conjugation functions ]=] -- Present forms with -e-, no j-vowels. present_e_a = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у", "ешь", "ет", "ем", "ете", "ут", note) end present_e_b = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у́", "ёшь", "ёт", "ём", "ёте", "у́т", note) end present_e_c = function(forms, stem, tr, note) append_pres_futr(forms, stem, tr, "у́", "ешь", "ет", "ем", "ете", "ут", note) end -- Present forms with -e- and iotated stem. ABC = "a", "b" or "c", indicating -- the accent pattern. If SHCH is set, iotate final т as щ, not ч. If NOTE -- is given, add it to each form. present_je = function(forms, stem, tr, abc, shch, note) local iotated_stem, iotated_tr = com.iotation(stem, tr, shch) assert(abc == "a" or abc == "b" or abc == "c") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local hushing = rfind(iotated_stem, "[шщжч]$") -- or no_iotation local ending_1sg = hushing and (abc == "a" and "у" or "у́") or not hushing and (abc == "a" and "ю" or "ю́") if abc == "b" then append_pres_futr(forms, iotated_stem, iotated_tr, {}, "ёшь", "ёт", "ём", "ёте", (hushing and "у́т" or "ю́т"), note) else append_pres_futr(forms, iotated_stem, iotated_tr, {}, "ешь", "ет", "ем", "ете", (hushing and "ут" or "ют"), note) end append_pres_futr(forms, iotated_stem, iotated_tr, ending_1sg, {}, {}, {}, {}, {}, note) end -- Present forms with -i- (and iotated stem in the 1sg). ABC = "a", "b" or "c", -- indicating the accent pattern. If SHCH is set, iotate final т as щ, not ч. -- If NOTE is given, add it to each form. present_i = function(forms, stem, tr, abc, shch, note) local iotated_stem, iotated_tr = com.iotation(stem, tr, shch) assert(abc == "a" or abc == "b" or abc == "c") -- Verbs ending in a hushing consonant do not get j-vowels in the endings. local iotated_hushing = rfind(iotated_stem, "[шщжч]$") local hushing = rfind(stem, "[шщжч]$") local ending_1sg = iotated_hushing and (abc == "a" and "у" or "у́") or not iotated_hushing and (abc == "a" and "ю" or "ю́") if abc == "b" then append_pres_futr(forms, stem, tr, {}, "и́шь", "и́т", "и́м", "и́те", hushing and "а́т" or "я́т", note) else append_pres_futr(forms, stem, tr, {}, "ишь", "ит", "им", "ите", hushing and "ат" or "ят", note) end append_pres_futr(forms, iotated_stem, iotated_tr, ending_1sg, {}, {}, {}, {}, {}, note) end -- Add the reflexive particle to all verb forms make_reflexive = function(forms, reflex_stress) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) local trentry, trnotes if tr then trentry, trnotes = m_table_tools.separate_notes(tr) end if is_vowel_stem(ruentry) then forms[key] = {ruentry .. "сь" .. runotes, trentry and trentry .. "sʹ" .. trnotes} -- if a past_m form doesn't contain a stress, add a stressed -- particle "ся́" if called for elseif reflex_stress and com.is_unstressed(ruentry) and rfind(key, "^past_m") then forms[key] = {ruentry .. "ся́" .. runotes, trentry and trentry .. "sja" .. AC .. trnotes} else forms[key] = {ruentry .. "ся" .. runotes, trentry and trentry .. "sja" .. trnotes} end end end end -- Convert verb forms to pre-reform style by adding ъ to consonant-final -- forms (excluding those ending in й and ь) and converting -ий to -ій and -- -ийся to -ійся make_pre_reform = function(forms) for key, form in pairs(forms) do local ru, tr = extract_russian_tr(form) -- check for empty string, dashes and nil's if ru and ru ~= "" and ru ~= "-" then local ruentry, runotes = m_table_tools.separate_notes(ru) if rfind(ruentry, "[бцдфгчклмнпрствшхзжщ]$") then forms[key] = {ruentry .. "ъ" .. runotes, tr} else forms[key] = {rsub(rsub(ruentry, "ий$", "ій"), "ийся$", "ійся") .. runotes, tr} end end end end local function setup_pres_futr(forms, perf, old) -- Copy the main form FROMFORM to the main form TOFORM, and copy all -- associated alternative forms. local function copy_form(fromform, toform) local fromforms = main_to_all_verb_forms[fromform] local toforms = main_to_all_verb_forms[toform] local numforms = #fromforms assert(#toforms == numforms) for i=1,numforms do forms[toforms[i]] = forms[fromforms[i]] end end -- Copy pres_futr_* to pres_* (imperfective) or futr_* (perfective). if perf then copy_form("pres_futr_1sg", "futr_1sg") copy_form("pres_futr_2sg", "futr_2sg") copy_form("pres_futr_3sg", "futr_3sg") copy_form("pres_futr_1pl", "futr_1pl") copy_form("pres_futr_2pl", "futr_2pl") copy_form("pres_futr_3pl", "futr_3pl") else copy_form("pres_futr_1sg", "pres_1sg") copy_form("pres_futr_2sg", "pres_2sg") copy_form("pres_futr_3sg", "pres_3sg") copy_form("pres_futr_1pl", "pres_1pl") copy_form("pres_futr_2pl", "pres_2pl") copy_form("pres_futr_3pl", "pres_3pl") end local futr_data = { {"futr_1sg", "бу́ду", "búdu"}, {"futr_2sg", "бу́дешь", "búdešʹ"}, {"futr_3sg", "бу́дет" .. (old and "ъ" or ""), "búdet"}, {"futr_1pl", "бу́дем" .. (old and "ъ" or ""), "búdem"}, {"futr_2pl", "бу́дете", "búdete"}, {"futr_3pl", "бу́дут" .. (old and "ъ" or ""), "búdut"} } local function insert_future(inf, inf_tr) for _, fut in ipairs(futr_data) do append_to_arg_chain(forms, fut[1], fut[1], {fut[2] .. inf, inf_tr and fut[3] .. inf_tr}) end end -- Insert future, if required (there may conceivably be multiple infitives). for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local infinitive = forms[form] if infinitive then local inf, inf_tr = extract_russian_tr(forms[form]) -- only for "бы́ть" the future forms are бу́ду, бу́дешь, etc. if inf == "бы́ть" then insert_future("", nil) elseif not perf then insert_future(" " .. inf, inf_tr and " " .. inf_tr) end end end end parse_and_stress_override = function(form, val, existing, all_existing) if rfind(form, "^pres_futr") then error("Overrides of pres_futr* are illegal, use pres_* or futr_*") end local allow_unaccented val, allow_unaccented = rsubb(val, "^%*", "") local ru, tr = nom.split_russian_tr(val) -- past_m can be unaccented in connection with reflex_stress=ся́ if not allow_unaccented and not rfind(form, "^past_m") then if tr and com.is_unstressed(ru) ~= com.is_unstressed(tr) then error("Override " .. form .. "=" .. ru .. " and translit " .. tr .. " must have same accent pattern") end if com.is_monosyllabic(ru) then ru, tr = com.make_ending_stressed(ru, tr) elseif com.needs_accents(ru) then error("Override " .. form .. "=" .. ru .. " requires an accent") end end if rfind(ru, "%+") then -- If either the existing or override has manual translit, the resulting -- form should have manual translit. We specify ALWAYS_TRANSLIT if -- the override has manual translit, so that we can substitute the -- existing translit into the override translit. local existing_ru, existing_tr = extract_russian_tr(existing, not not tr) -- used especially for present participles; substitute existing form, -- minus any "awkward-" or "none-" prefixes. ru = rsub(ru, "%+", strip_arg_status_prefix(existing_ru)) -- If there's existing translit but not in the override, make sure it's -- carried along. if existing_tr and not tr then tr = com.translit(ru) end tr = tr and rsub(tr, "%+", strip_arg_status_prefix(existing_tr)) end -- If there's an override and it doesn't match an existing form, it's -- irregular and indicate it using the IRREG marker. We don't do this if -- the override simply removes a form. We do do this if there aren't any -- existing forms, on the theory that the presence of a form when none is -- normally called for is an irregularity. When comparing against the -- existing forms, strip any status prefix (e.g. 'awkward-'). if all_existing then local all_existing_stripped = {} for _, ae in ipairs(all_existing) do local existing_ru, existing_tr = extract_russian_tr(ae) existing_ru = strip_arg_status_prefix(existing_ru) existing_tr = existing_tr and strip_arg_status_prefix(existing_tr) table.insert(all_existing_stripped, {existing_ru, existing_tr}) end if ru ~= "-" and not contains_form(all_existing_stripped, {ru, tr}) then ru = ru .. IRREG tr = tr and tr .. IRREG end end return {ru, tr} end -- Set up pres_* or futr_*; handle *sym/*tail/*tailall notes and overrides. handle_forms_and_overrides = function(args, forms, data) setup_pres_futr(forms, data.perf, data.old) local function append_value(forms, prop, value) if forms[prop] and forms[prop] ~= "" and forms[prop] ~= "-" then value = nom.split_russian_tr(value, "dopair") local curval = forms[prop] if type(curval) == "string" then curval = {curval} end forms[prop] = nom.concat_paired_russian_tr(curval, value) end end local function append_note_all(forms, proplist, value) for _, prop in ipairs(proplist) do append_value(forms, prop, value) end end local function append_note_last(forms, proplist, value, gt_one) local numprops = 0 local lastprop -- Find the last property in the series with a value for _, prop in ipairs(proplist) do if forms[prop] and forms[prop] ~= "" and forms[prop] ~= "-" then numprops = numprops + 1 lastprop = prop end end if numprops > (gt_one and 1 or 0) then append_value(forms, lastprop, value) end end for _, proplist in ipairs(all_verb_forms) do local vallist = {} -- Handle PROP_sym, which applies to all overridable properties, including -- alternative forms, and applies to exactly that property. for _, prop in ipairs(proplist) do if args[prop .. "_sym"] then append_value(forms, prop, args[prop .. "_sym"]) end end local propname = proplist[1] -- Handle PROP_tail, which applies to a series of properties (e.g. past_m, -- past_m2, ...) and appends to the last one. if args[propname .. "_tail"] then append_note_last(forms, proplist, args[propname .. "_tail"]) end -- Handle PROP_tailall, which applies to a series of properties and -- appends to all. if args[propname .. "_tailall"] then append_note_all(forms, proplist, args[propname .. "_tailall"]) end end -- Now handle pasttail, pasttailall, prestail, prestailall, etc. -- Table listing tail-arg prefix and corresponding verb forms. local tailargs = { {"past", past_verb_forms}, {"pres", pres_verb_forms}, {"futr", futr_verb_forms}, {"impr", impr_verb_forms}, {"part", part_verb_forms}, {"prespart", pres_part_verb_forms}, {"pastpart", past_part_verb_forms}, {"", all_main_verb_forms} } for _, tailspec in ipairs(tailargs) do tailforms = tailspec[2] -- Handle the ...tail variants. tailarg = tailspec[1] .. "tail" if args[tailarg] then track(tailarg) for _, prop in ipairs(tailforms) do append_note_last(forms, main_to_all_verb_forms[prop], args[tailarg], ">1") end end -- Handle the ...tailall variants. tailallarg = tailspec[1] .. "tailall" if args[tailallarg] then track(tailallarg) for _, prop in ipairs(tailforms) do append_note_all(forms, main_to_all_verb_forms[prop], args[tailallarg]) end end end --handle overrides (formerly we only had past_pasv_part as a --general override, plus scattered main-form overrides in particular --conjugation classes) for _, all_forms in pairs(main_to_all_verb_forms) do local i = 0 local orig_forms = {} for _, form in ipairs(all_forms) do if forms[form] then table.insert(orig_forms, forms[form]) end end for _, form in ipairs(all_forms) do i = i + 1 -- If we auto-generated the past passive participle in order to -- check for irregular overrides, make sure to erase any such -- participles that weren't overridden. This happens for example -- in обнять, where there are two automatically generated past -- passive participles but a single ppp=о́внятый override. local override = args[form] or ( data.ppp_auto_generated and rfind(form, "^past_pasv_part") and "-" ) if override then forms[form] = parse_and_stress_override(form, override, forms[form], orig_forms) elseif i == 1 then forms[form] = forms[form] or "" end end end end -- Finish generating the forms; primarily, clear out unused forms. finish_generating_forms = function(forms, data) -- Convert any main form that's nil (meaning no forms at all corresponding -- to this main form) to the empty string. for main_form, _ in pairs(main_to_all_verb_forms) do if not forms[main_form] then forms[main_form] = "" end end -- Set the main form FORM to the empty string, and corresponding alt forms -- to nil. local function clear_form(form) local i = 0 for _, altform in ipairs(main_to_all_verb_forms[form]) do i = i + 1 if i == 1 then forms[altform] = "" else forms[altform] = nil end end end -- Intransitive and reflexive verbs have no passive participles -- (unless has_prpp=y and/or has_ppp=y). if data.intr or data.refl then if not data.has_prpp then clear_form("pres_pasv_part") end if not data.has_ppp then clear_form("past_pasv_part") end end if data.refl then -- no past_adv_part_short for reflexive verbs clear_form("past_adv_part_short") end -- Impersonal verbs normally have no passive participles, but allow them -- if there's specifically an override. We only do this for the present -- passive participle because the past passive participle isn't inserted -- by default, and we still want +p to work, which doesn't currently set -- data.ppp_override. if data.impers and not data.prpp_override then clear_form("pres_pasv_part") end if data.impers then clear_form("pres_1sg") clear_form("pres_2sg") clear_form("pres_1pl") clear_form("pres_2pl") clear_form("pres_3pl") clear_form("futr_1sg") clear_form("futr_2sg") clear_form("futr_1pl") clear_form("futr_2pl") clear_form("futr_3pl") clear_form("past_m") clear_form("past_f") clear_form("past_pl") clear_form("past_m_short") clear_form("past_f_short") clear_form("past_pl_short") clear_form("pres_actv_part") clear_form("past_actv_part") clear_form("pres_adv_part") clear_form("past_adv_part") clear_form("past_adv_part_short") clear_form("impr_sg") clear_form("impr_pl") end -- Perfective and iterative verbs have no present forms, as well as -- verbs marked nopres=1. if data.perf or data.iter or data.nopres then clear_form("pres_actv_part") clear_form("pres_pasv_part") clear_form("pres_adv_part") clear_form("pres_1sg") clear_form("pres_2sg") clear_form("pres_3sg") clear_form("pres_1pl") clear_form("pres_2pl") clear_form("pres_3pl") end -- Some verbs (e.g. грясти́, густи́) have no past if data.nopast then clear_form("past_m") clear_form("past_f") clear_form("past_n") clear_form("past_pl") clear_form("past_m_short") clear_form("past_f_short") clear_form("past_n_short") clear_form("past_pl_short") clear_form("past_actv_part") clear_form("past_pasv_part") clear_form("past_adv_part") clear_form("past_adv_part_short") end -- Iterative verbs and verbs marked noimpr=1 have no imperative forms. if data.iter or data.noimpr then clear_form("impr_sg") clear_form("impr_pl") end -- Iterative verbs and verbs marked nofutr=1 have no future forms. if data.iter or data.nofutr then clear_form("futr_1sg") clear_form("futr_2sg") clear_form("futr_3sg") clear_form("futr_1pl") clear_form("futr_2pl") clear_form("futr_3pl") end --handle "none-" and "awkward-" prefixes (used especially for pres_pasv_part) local footnote_sym = nil for _, all_forms in pairs(main_to_all_verb_forms) do local i = 0 for _, form in ipairs(all_forms) do i = i + 1 if forms[form] then local formru, formtr = extract_russian_tr(forms[form]) if rfind(formru, "^none%-") then if i == 1 then forms[form] = "" else forms[form] = nil end elseif rfind(formru, "^awkward%-") then if not footnote_sym then footnote_sym = next_note_symbol(data) ut.insert_if_not(data.internal_notes, footnote_sym .. " Rare and awkward.") end forms[form] = {rsub(formru, "^awkward%-", "") .. footnote_sym, formtr and rsub(formtr, "^awkward%-", "") .. footnote_sym} end end end end --Insert footnote for IRREG symbol if present. for _, all_forms in pairs(main_to_all_verb_forms) do for _, form in ipairs(all_forms) do if forms[form] then local formru, formtr = extract_russian_tr(forms[form]) if rfind(formru, IRREG) then ut.insert_if_not(data.internal_notes, IRREG .. " Irregular.") end end end end end local accel_forms = { -- present tense pres_1sg = "1|s|pres|ind", pres_2sg = "2|s|pres|ind", pres_3sg = "3|s|pres|ind", pres_1pl = "1|p|pres|ind", pres_2pl = "2|p|pres|ind", pres_3pl = "3|p|pres|ind", -- future tense futr_1sg = "1|s|fut|ind", futr_2sg = "2|s|fut|ind", futr_3sg = "3|s|fut|ind", futr_1pl = "1|p|fut|ind", futr_2pl = "2|p|fut|ind", futr_3pl = "3|p|fut|ind", -- imperative impr_sg = "2|s|imp", impr_pl = "2|p|imp", -- past past_m = "m|s|past|ind", past_f = "f|s|past|ind", past_n = "n|s|past|ind", past_pl = "p|past|ind", past_m_short = "short|m|s|past|ind", past_f_short = "short|f|s|past|ind", past_n_short = "short|n|s|past|ind", past_pl_short = "short|p|past|ind", -- active participles pres_actv_part = "pres|act|part", past_actv_part = "past|act|part", -- passive participles pres_pasv_part = "pres|pass|part", past_pasv_part = "past|pass|part", -- adverbial participles pres_adv_part = "pres|adv|part", past_adv_part = "past|adv|part", past_adv_part_short = "short|past|adv|part", -- infinitive infinitive = "inf", } -- Make the table make_table = function(forms, title, perf, intr, impers, notes, internal_notes, old) local infinitives = {} for _, form in ipairs(main_to_all_verb_forms["infinitive"]) do local infinitive = forms[form] if infinitive then local inf, inf_tr = extract_russian_tr(forms[form]) if inf ~= "-" then ut.insert_if_not(infinitives, inf) end end end -- Group forms together for a given key and combine adjacent forms with the same -- Russian (they should always have different translits). Take care not to introduce -- manual translit unnecessarily. local grouped_forms = {} for dispform, sourceforms in pairs(disp_verb_form_map) do local entry = {} for _, form in ipairs(sourceforms) do local ru, tr = extract_russian_tr(forms[form]) -- check for empty strings, dashes and nil's if ru and ru ~= "" and ru ~= "-" and ru ~= "&mdash;" then if #entry > 0 then local lastru, lasttr = extract_russian_tr(entry[#entry]) if lastru == ru then if not lasttr and not tr or lasttr == tr then error("Russian form " .. ru .. " is duplicated, probably due to a duplicative override") end lasttr = lasttr or com.translit(lastru) tr = tr or com.translit(ru) entry[#entry] = {ru, lasttr .. " ''or'' " .. tr} else table.insert(entry, {ru, tr}) end else table.insert(entry, {ru, tr}) end end end grouped_forms[dispform] = entry end local title = (old and "Pre-reform conjugation" or "Conjugation") .. (#infinitives == 0 and "" or " of <span lang=\"ru\" class=\"Cyrl\">''" .. table.concat(infinitives, ", ") .. "''</span>") .. (title and " (" .. title .. ")" or "") local function add_links(ru, rusuf, runotes, tr, trnotes, accel) local ruspan if old then ruspan = m_links.full_link({lang = lang, term = com.remove_jo(ru), accel = accel, alt = not ru:find("[[", 1, true) and ru, tr = "-"}) else ruspan = m_links.full_link({lang = lang, term = ru, accel = accel, tr = "-"}) end if rusuf ~= "" then rusuf = "<span lang=\"ru\" class=\"Cyrl\">" .. rusuf .. "</span>" end return ruspan .. rusuf .. runotes .. "<br/>" .. require("Modül:alfabe araçları").tag_translit(tr .. trnotes, lang, "default", 'style="color: #888"') end -- NOTE: No need to check for multiple infinitives because the accel system -- doesn't support multiple lemmas. local lemma, lemmatr = extract_russian_tr(forms["infinitive"]) -- check for empty strings, dashes and nil's if lemma and lemma ~= "" and lemma ~= "-" and lemma ~= "&mdash;" then lemma, _ = m_table_tools.separate_notes(lemma) if lemmatr then lemmatr, _ = m_table_tools.separate_notes(lemmatr) end else -- In case the lemma is an empty string or dash, set to nil so we don't -- set a lemma in the accelerator and fall back to the page name. lemma = nil lemmatr = nil end -- Convert to displayed form local disp = {} for key, entry in pairs(grouped_forms) do for i, form in ipairs(entry) do local ru, origtr = extract_russian_tr(form) local tr = origtr or ru and com.translit(ru) local ruentry, runotes = m_table_tools.get_notes(ru) local trentry, trnotes = m_table_tools.get_notes(tr) local accel_form = accel_forms[key] if not accel_form then error("Unrecognized key " .. key .. " when looking up accelerator form") end local accel if origtr and origtr:find(" ''or'' ") then -- Multiple translits for a given Russian term. -- FIXME! Support this. accel = nil else accel = { form = accel_form, translit = origtr, lemma = lemma, lemma_translit = lemmatr} end if rfind(key, "^futr") then -- Add link to first word (form of 'to be') tobe, inf = rmatch(ruentry, "^([^ ]*) ([^ ]*)$") if tobe then -- No accelerators for imperfective future, as it's just the future of "to be" -- plus the infinitive. entry[i] = add_links(tobe, " " .. inf, runotes, trentry, trnotes, nil) else entry[i] = add_links(ruentry, "", runotes, trentry, trnotes, accel) end else entry[i] = add_links(ruentry, "", runotes, trentry, trnotes, accel) end end disp[key] = table.concat(entry, ",<br/>") if disp[key] == "" then disp[key] = "&mdash;" end end local all_notes = {} for _, note in ipairs(internal_notes) do local symbol, entry = m_table_tools.get_initial_notes(note) table.insert(all_notes, symbol .. entry) end for _, note in ipairs(notes) do local symbol, entry = m_table_tools.get_initial_notes(note) table.insert(all_notes, symbol .. entry) end local notes_text table.insert(all_notes, 1, "Note: For declension of participles, see their entries. Adverbial participles are indeclinable.") notes_text = table.concat(all_notes, "<br />") .. "\n" return require("Modül:TemplateStyles")("Modül:ru-eylem/style.css") .. [=[<div class="NavFrame" style="width:49.6em;"> <div class="NavHead" style="text-align:left; background:#e0e0ff;">]=] .. title .. [=[</div> <div class="NavContent"> {| class="inflection inflection-ru inflection-verb inflection-table" |+ ]=] .. notes_text .. [=[ |- class="rowgroup" ! colspan="3" | ]=] .. (perf and [=[[[совершенный вид|perfective aspect]]]=] or [=[[[несовершенный вид|imperfective aspect]]]=]) .. [=[ |- ! [[неопределённая форма|infinitive]] | colspan="2" | ]=] .. disp.infinitive .. [=[ |- class="rowgroup" ! style="width:15em" | [[причастие|participles]] ! [[настоящее время|present tense]] ! [[прошедшее время|past tense]] |- ! [[действительный залог|active]] | ]=] .. disp.pres_actv_part .. [=[ || ]=] .. disp.past_actv_part .. [=[ |- ! [[страдательный залог|passive]] | ]=] .. disp.pres_pasv_part .. [=[ || ]=] .. disp.past_pasv_part .. [=[ |- ! [[деепричастие|adverbial]] | ]=] .. disp.pres_adv_part .. [=[ || ]=] .. disp.past_adv_part .. [=[ |- class="rowgroup" ! ! [[настоящее время|present tense]] ! [[будущее время|future tense]] |- ! [[первое лицо|1st]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">я</span>) | ]=] .. disp.pres_1sg .. [=[ || ]=] .. disp.futr_1sg .. [=[ |- ! [[второе лицо|2nd]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">ты</span>) | ]=] .. disp.pres_2sg .. [=[ || ]=] .. disp.futr_2sg .. [=[ |- ! [[третье лицо|3rd]] [[единственное число|singular]] (<span lang="ru" class="Cyrl">он/она́/оно́</span>) | ]=] .. disp.pres_3sg .. [=[ || ]=] .. disp.futr_3sg .. [=[ |- ! [[первое лицо|1st]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">мы</span>) | ]=] .. disp.pres_1pl .. [=[ || ]=] .. disp.futr_1pl .. [=[ |- ! [[второе лицо|2nd]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">вы</span>) | ]=] .. disp.pres_2pl .. [=[ || ]=] .. disp.futr_2pl .. [=[ |- ! [[третье лицо|3rd]] [[множественное число|plural]] (<span lang="ru" class="Cyrl">они́</span>) | ]=] .. disp.pres_3pl .. [=[ || ]=] .. disp.futr_3pl .. [=[ |- class="rowgroup" ! [[повелительное наклонение|imperative]] ! [[единственное число|singular]] ! [[множественное число|plural]] |- ! | ]=] .. disp.impr_sg .. [=[ || ]=] .. disp.impr_pl .. [=[ |- class="rowgroup" ! [[прошедшее время|past tense]] ! [[единственное число|singular]] ! [[множественное число|plural]]<br/>(<span lang="ru" class="Cyrl">мы/вы/они́</span>) |- ! [[мужской род|masculine]] (<span lang="ru" class="Cyrl">я/ты/он</span>) | ]=] .. disp.past_m .. [=[ || rowspan="3" | ]=] .. disp.past_pl .. [=[ |- ! [[женский род|feminine]] (<span lang="ru" class="Cyrl">я/ты/она́</span>) | ]=] .. disp.past_f .. [=[ |- ! style="background-color: #ffffe0;" | [[средний род|neuter]] (<span lang="ru" class="Cyrl">оно́</span>) | ]=] .. disp.past_n .. [=[ |} </div> </div>]=] end return export -- For Vim, so we get 4-space tabs -- vim: set ts=4 sw=4 noet: gcr17s4n934y6n22i13264uu1outam8 Modül:require when needed 828 1591008 5672501 2026-06-29T15:12:10Z MustafaCavlak 59368 imported from en 5672501 Scribunto text/plain local getmetatable = getmetatable local ipairs = ipairs local loaded = package.loaded local pairs = pairs local require = require local select = select local setmetatable = setmetatable local tostring = tostring local unpack = unpack or table.unpack -- Lua 5.2 compatibility local function get_nested(obj, ...) local n = select("#", ...) if n == 0 then return obj end obj = obj[...] for i = 2, n do obj = obj[select(i, ...)] end return obj end local function get_obj(mt) local obj = require(mt[1]) if #mt > 1 then obj = get_nested(obj, unpack(mt, 2)) end mt[0] = obj return obj end local function __call(self, ...) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return obj(...) end local function __index(self, k) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return obj[k] end local function __ipairs(self) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return ipairs(obj) end local function __newindex(self, k, v) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end obj[k] = v end local function __pairs(self) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return pairs(obj) end local function __tostring(self) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return tostring(obj) end return function(modname, ...) local mod = loaded[modname] if mod ~= nil then return get_nested(mod, ...) end return setmetatable({}, { modname, __call = __call, __index = __index, __ipairs = __ipairs, __newindex = __newindex, __pairs = __pairs, __tostring = __tostring, -- TODO: other metamethods, if needed. ... }) end 1p8upm5p2cm943t5atixatwvtsenpe2 Modül:table/getUnprotectedMetatable 828 1591009 5672505 2026-06-29T15:31:55Z MustafaCavlak 59368 imported from en 5672505 Scribunto text/plain local _getmetatable = debug.getmetatable -- For testing (and just in case it gets enabled). if _getmetatable ~= nil then -- Avoid debug.getmetatable() throwing an error if 0 arguments are passed, -- for parity with the other function. return function(t) return _getmetatable(t) end end _getmetatable = getmetatable local pcall = pcall local rawget = rawget local setmetatable = setmetatable local type = type --[==[ Attempts to retrieve the input value's metatable, and returns it if found. If the value does not have a metatable, returns {nil}. If the input value does have a metatable, but that metatable is not possible to retrieve because it is protected with the `__metatable` metamethod, returns {false}. This is a useful way to ensure that functions can reliably distinguish between objects that do not have metamethods, objects with known metamethods, and objects with unknown metamethods.]==] return function(t) local mt = _getmetatable(t) -- If `mt` is nil, there's no metatable. if mt == nil then return nil -- If `mt` is not a table, the real metatable is protected and there's no -- way of retrieving it. elseif type(mt) ~= "table" then return false end -- Try setting `mt` as the metatable with `setmetatable`; if the metatable -- is protected, this will cause an error to be thrown (revealing it as -- protected), and if it isn't, then `mt` must be the real metatable anyway, -- so nothing has changed. Also make a special exception for data loaded via -- mw.loadData(), which sets each metatable at its own __metatable key as a -- way to stop the use of setmetatable() without actually hiding it. This is -- spoofable, but low-risk. return (pcall(setmetatable, t, mt) or rawget(mt, "mw_loadData") == true) and mt or false end oqd72lzzcljldqpmbzxsx5fm947exar Modül:table/getMetamethod 828 1591010 5672506 2026-06-29T15:36:08Z MustafaCavlak 59368 imported from en 5672506 Scribunto text/plain local table_get_unprotected_metatable = "Modül:table/getUnprotectedMetatable" local rawget = rawget local select = select local function get_unprotected_metatable(...) get_unprotected_metatable = require(table_get_unprotected_metatable) return get_unprotected_metatable(...) end local function get_metamethod(n, i, mt, mm, ...) if mt then mm = rawget(mt, mm) else mm = nil end if i == n then return mm end return mm, get_metamethod(n, i + 1, mt, ...) end --[==[ Takes an input value and any number of metamethods, and attempts to retrieve the values at those keys in the value's metatable. Returns a boolean stating whether the value's metamethods are findable, followed by a return value for each metamethod. A value's metamethods are findable if it does not have a protected metatable, so the first return value is {true} if the value either has a metatable which does not contain the {__metatable} metamethod, or it has no metatable at all. If the value does have a protected metatable, the first return value is {false}, and all remaining return values default to {nil}.]==] return function(t, ...) local mt, n = get_unprotected_metatable(t), select("#", ...) -- get_unprotected_metatable() returns the metatable if it's unprotected, -- false if it's protected, or nil if there is no metatable. It checks -- whether a metatable is protected by trying pcall(setmetatable, t), -- so it's always possible to determine accurately. if n == 0 then return mt ~= false end return mt ~= false, get_metamethod(n, 1, mt, ...) end skbyag86pbpny59d8nma70atje78exb Modül:fun/isCallable 828 1591011 5672507 2026-06-29T15:36:36Z MustafaCavlak 59368 imported from en 5672507 Scribunto text/plain local debug_track_module = "Modül:debug/track" local table_get_metamethod_module = "Modül:table/getMetamethod" local require = require local type = type local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function get_metamethod(...) get_metamethod = require(table_get_metamethod_module) return get_metamethod(...) end --[==[ Return {true} if the input is a function or functor (an object which can be called like a function, because it has a {__call} metamethod). Note: if the input is an object with a {__call} metamethod, but this function is not able to find it because the object's metatable is protected with {__metatable}, then it will return {false} by default, or {nil} if the {allow_maybe} flag is set.]==] return function(obj, allow_maybe) if type(obj) == "function" then return true end -- An object is callable if it has a __call metamethod, so try to get it -- with get_metamethod(). local success, __call = get_metamethod(obj, "__call") -- If this succeeds, `obj` will only be callable if the __call metamethod is -- a function (i.e. it can't itself be a callable table), so don't recurse -- to check it. if __call and type(__call) == "function" then return true -- If not, then the metatable is protected, so it's not possible to know if -- `obj` is callable without actually calling it. elseif not success then debug_track("fun/isCallable/protected metatable") if allow_maybe then return nil end end return false end q2uw0kspncmdq9uyy3cxjm1xqg59xc3 Modül:string/patternEscape 828 1591012 5672508 2026-06-29T15:39:14Z MustafaCavlak 59368 imported from en 5672508 Scribunto text/plain local gsub = string.gsub local chars local function get_chars() chars, get_chars = { ["\000"] = "%z", ["$"] = "%$", ["%"] = "%%", ["("] = "%(", [")"] = "%)", ["*"] = "%*", ["+"] = "%+", ["-"] = "%-", ["."] = "%.", ["?"] = "%?", ["["] = "%[", ["]"] = "%]", ["^"] = "%^", }, nil return chars end --[==[Escapes the magic characters used in a pattern: {$%()*+-.?[]^}, and converts the null character to {%z}. For example, {"^$()%.[]*+-?\0"} becomes {"%^%$%(%)%%%.%[%]%*%+%-%?%z"}. This is necessary when constructing a pattern involving arbitrary text (e.g. from user input).]==] return function(str) return (gsub(str, "[%z$%%()*+%-.?[%]^]", chars or get_chars())) end kdhwp5dohwvh931huz7m0oufqqh05wl Modül:string/replacementEscape 828 1591013 5672509 2026-06-29T15:40:35Z MustafaCavlak 59368 imported from en 5672509 Scribunto text/plain local gsub = string.gsub --[==[Escapes {%}, which is the only magic character used in replacement strings, which are given as the third argument to {string.gsub} and {mw.ustring.gsub}, as well as format strings given to {string.format} and {mw.ustring.format}.]==] return function(str) return (gsub(str, "%%", "%%%%")) end aid90he3azqkc4qrytnczmfsjczbfe3 Modül:başlık başı araçları 828 1591014 5672510 2026-06-29T15:41:54Z MustafaCavlak 59368 imported from en 5672510 Scribunto text/plain local export = {} local fun_is_callable_module = "Modül:fun/isCallable" local languages_module = "Modül:diller" local links_module = "Modül:bağlantılar" local parse_utilities_module = "Modül:parse utilities" local string_pattern_escape_module = "Modül:string/patternEscape" local string_replacement_escape_module = "Modül:string/replacementEscape" local string_utilities_module = "Modül:string araçları" local table_module = "Modül:table" local dump = mw.dumpObject local unpack = unpack or table.unpack -- Lua 5.2 compatibility local insert = table.insert local concat = table.concat local remove = table.remove local sort = table.sort local function deepEquals(...) deepEquals = require(table_module).deepEquals return deepEquals(...) end local function escape_wikicode(...) escape_wikicode = require(parse_utilities_module).escape_wikicode return escape_wikicode(...) end local function extend(...) extend = require(table_module).extend return extend(...) end local function get_lang(...) get_lang = require(languages_module).getByCode return get_lang(...) end local function insert_if_not(...) insert_if_not = require(table_module).insertIfNot return insert_if_not(...) end local function is_callable(...) is_callable = require(fun_is_callable_module) return is_callable(...) end local function parse_inline_modifiers(...) parse_inline_modifiers = require(parse_utilities_module).parse_inline_modifiers return parse_inline_modifiers(...) end local function pattern_escape(...) pattern_escape = require(string_pattern_escape_module) return pattern_escape(...) end local function replacement_escape(...) replacement_escape = require(string_replacement_escape_module) return replacement_escape(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function term_contains_top_level_html(...) term_contains_top_level_html = require(parse_utilities_module).term_contains_top_level_html return term_contains_top_level_html(...) end local function ugsub(...) ugsub = require(string_utilities_module).gsub return ugsub(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end local param_mods = { id = {}, -- disabled when `is_head = true` q = {type = "qualifier"}, qq = {type = "qualifier"}, l = {type = "labels"}, ll = {type = "labels"}, -- [[Modül:başlık başı]] expects part references in `.refs`. ref = {item_dest = "refs", type = "references", store = "insert-flattened"}, } local optional_param_mods = { g = {item_dest = "genders", type = "genders"}, alt = {}, lang = {type = "language"}, sc = {type = "script"}, t = {item_dest = "gloss"}, gloss = {}, pos = {}, lit = {}, tr = {}, ts = {}, face = {}, nolinkinfl = {type = "boolean"}, } local optional_headword_param_mods = { sc = {type = "script"}, tr = {}, ts = {}, } --[==[ Parse a single inflection or headword form or list of such forms. In either case, inline modifiers may be attached. `data` is an object with the following fields: * `val`: The raw value to parse. Required. * `paramname`: The name of the parameter from which the value was taken; used in error messages. Required. * `is_head`: We are parsing a headword parameter (a value which goes into the `heads` field of `data`). This changes the allowed modifiers, disabling the `id` modifier and only allowing a subset of optional modifiers. * `frob`: An optional function of one value to apply to the form after inline modifiers have been removed (i.e. to apply to the `.term` field of the returned object). * `include_mods`: List of extra inline modifiers to include, besides the default ones (see below). Each list item is either a string specifying a recognized extra inline modifier (see `optional_param_mods` in the code), or a two-item list of modifier name and modifier spec, where the spec should follow the syntax for modifier specs in `parse_inline_modifiers` in [[Modül:parse utilities]]. * `exclude_mods`: List of default inline modifiers to not include. * `splitchar`: If specified, the value in `val` can be a list of forms to parse, separated by the value of `splitchar` (which is a Lua pattern, as in `parse_inline_modifiers` in [[Modül:parse utilities]]). Most commonly, `splitchar` is a single comma and the values are comma-separated (in this case, splitting will not happen if a space follows the comma). * `preserve_splitchar`, `delimiter_key`, `escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_inline_modifiers` in [[Modül:parse utilities]]. Returns an object suitable for storing as one element of one of the lists in `headdata.inflections`, where `headdata` is the structure passed to [[Modül:başlık başı]]. If `splitchar` is specified, howeve, the return value is a list of such objects. The following default inline modifiers are currently recognized: * `q`: Left qualifier. * `qq`: Right qualifier. * `l`: Comma-separated list of left labels. No space should follow the comma. * `ll`: Comma-separated list of right labels. No space should follow the comma. * `ref`: Reference or references. See {{tl|IPA}} for the syntax. * `id`: Sense ID, in case there are multiple senses. See {{tl|l}}. The following are the recognized additional inline modifiers: * `g`: Comma-separated list of genders. * `alt`: Display text. * `lang`: Language code of language of the form, if different from the language of the headword. * `sc`: Script code of script of the form. Almost never needed. * `t`: Gloss for the form. * `gloss`: Gloss for the form (alias for `t`). * `pos`: Part of speech of the form. * `lit`: Literal meaning of the form. * `tr`: Manual transliteration of the form. * `ts`: Transcription of the form, for languages where the transliteration differs markedly from the pronunciation. * `face`: Face to display the form in, e.g. {"hypothetical"} for a hypothetical form (unlinkable and displayed in italics). * `nolinkinfl`: Make the form unlinkable. ]==] function export.parse_term_with_modifiers(data) local paramname, val, frob = data.paramname, data.val, data.frob local function generate_obj(term, parse_err) if frob then term = frob(term, parse_err) end return {term = term} end -- Check for inline modifier, e.g. מרים<tr:Miryem>. But exclude top-level HTML entry with <span ...>, -- <sup> or similar in it. if (val:find("<", nil, true) or data.splitchar) and not term_contains_top_level_html(val) and -- don't parse inline modifiers if is_head and the value begins with a ~ (link modifier syntax) (not data.is_head or not val:find("^~")) then local param_mods = param_mods if data.is_head then param_mods = shallow_copy(param_mods) param_mods.id = nil end if data.include_mods or data.exclude_mods then if not data.is_head then -- already copied when data.is_head param_mods = shallow_copy(param_mods) end if data.include_mods then local optional_mods = data.is_head and optional_headword_param_mods or optional_param_mods for _, mod in ipairs(data.include_mods) do if type(mod) == "table" then if #mod ~= 2 then error(("Internal error: Modifier spec %s in `include_mods` should be of length 2"):format( dump(mod))) end local modkey, modvalue = unpack(mod) param_mods[modkey] = modvalue elseif not optional_mods[mod] then error(("Internal error: Unrecognized modifier spec %s in `include_mods`"):format( dump(mod))) else param_mods[mod] = optional_mods[mod] end end end if data.exclude_mods then for _, mod in ipairs(data.exclude_mods) do if not param_mods[mod] then error(("Internal error: Modifier spec %s in `exclude_mods` not found among existing modifiers" ):format(dump(mod))) else param_mods[mod] = nil end end end end return parse_inline_modifiers(val, { paramname = paramname, param_mods = param_mods, generate_obj = generate_obj, splitchar = data.splitchar, preserve_splitchar = data.preserve_splitchar, delimiter_key = data.delimiter_key, escape_fun = data.escape_fun, unescape_fun = data.unescape_fun, pre_normalize_modifiers = data.pre_normalize_modifiers, }) else local retval = generate_obj(val) if data.splitchar then retval = {retval} end return retval end end --[==[ Parse a list of inflection forms that may have inline modifiers attached. `data` is an object with the following fields: * `forms`: The list of raw values to parse. Required. * `paramname`: The name of the first parameter from which the value was taken; used in error messages. If this is a two-element list, the first element is the first parameter and the second element is the prefix of the remaining parameters. Parameter names that are numbers are handled correctly, as are those with \1 in it marking where the parameter index goes. Required. * `qualifiers`: If specified, a possibly gappy list of left qualifiers to add to the parsed terms (for compatibility purposes). * `splitchar`: As in `parse_term_with_modifiers()`. The resulting per-term lists will be flattened. * `frob`, `include_mods`, `exclude_mods`, `is_head`, `preserve_splitchar`, `delimiter_key`, `escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_term_with_modifiers()`. Returns a list of objects, suitable for storing as one of the lists in `headdata.inflections` (once a label is added), where `headdata` is the structure passed to [[Modül:başlık başı]]. ]==] function export.parse_term_list_with_modifiers(data) local paramname, forms = data.paramname, data.forms local qualifiers = data.qualifiers local first, restpref if type(paramname) == "table" then first = paramname[1] restpref = paramname[2] else first = paramname restpref = paramname end local terms = {} data = shallow_copy(data) for i, val in ipairs(forms) do data.paramname = i == 1 and first or type(restpref) == "number" and restpref + i - 1 or restpref:find("\1", nil, true) and restpref:gsub("\1", tostring(i)) or restpref .. i data.val = val local parsed = export.parse_term_with_modifiers(data) if qualifiers and qualifiers[i] then if data.splitchar then for _, term in ipairs(parsed) do term.q = {qualifiers[i]} end else parsed.q = {qualifiers[i]} end end if data.splitchar then extend(terms, parsed) else terms[i] = parsed end end return terms end --[==[ Construct a link to [[Appendix:Glossary]] for `entry`. If `text` is specified, it is the display text; otherwise, `entry` is used. ]==] function export.glossary_link(entry, text) text = text or entry return "[[Appendix:Glossary#" .. entry .. "|" .. text .. "]]" end function export.replace_glossary_links_in_label(label) if label:find("<<", nil, true) then label = label:gsub("<<(.-)|(.-)>>", export.glossary_link):gsub("<<(.-)>>", export.glossary_link) end return label end function export.insert_fixed_inflection(data) local headdata, origterm, label = data.headdata, data.originating_term, data.label local inflobj = data.inflobj or headdata inflobj.inflections = inflobj.inflections or {} if not origterm then insert(inflobj.inflections, { label = export.replace_glossary_links_in_label(label) }) else if origterm.id then error(("It doesn't make sense to pass in an ID '%s' for label '%s' in conjunction with a term value '%s'" ):format(origterm.id, label, origterm.term)) end -- Preserve qualifiers, labels, references origterm.term = nil origterm.label = export.replace_glossary_links_in_label(label) insert(inflobj.inflections, origterm) end end --[==[ Insert previously-parsed terms into an `inflections` field. The `inflections` field will be initialized if needed. `data` is an object with the following fields: * `headdata`: The headword structure passed to [[Modül:başlık başı]]. Required. * `inflobj`: The object whose `inflections` field the terms are inserted into. Defaults to `headdata`. Only needs to be set for nested inflections, which are specified for an inflection object rather than the headword data structure as a whole. * `terms`: The list of parsed terms. If {nil} or omitted, nothing happens unless `request` is set. * `label`: The label that the inflections are given; any parts of the label surrounded in <<...>> are linked to the glossary. (If the contents of <<...> contain a | in them, they are a two-part link.) Required. * `no_label`: If the term is {"-"} and there are no other terms, insert a fixed label with this value. Defaults to {"no "} plus the label. * `usually_no_label`: If the term is {"-"} and there are other terms, insert a fixed label with this value. Defaults to {"usually no "} plus the label. * `accel`: If specified, a full accelerator object to add to the inflections. * `request`: If specified and no terms are given, insert a label with a request for inflections to be given. * `enable_auto_translit`: If specified and terms are given, display automatic transliteration of the terms. ]==] function export.insert_inflection(data) local headdata, terms, label = data.headdata, data.terms, data.label local inflobj = data.inflobj or headdata if terms and terms[1] then if terms[1].term == "-" then if terms[2] then export.insert_fixed_inflection { headdata = headdata, inflobj = inflobj, originating_term = terms[1], label = data.usually_no_label or "usually no " .. label, } remove(terms, 1) else export.insert_fixed_inflection { headdata = headdata, inflobj = inflobj, originating_term = terms[1], label = data.no_label or "no " .. label, } return end end if data.check_missing then error("check_missing support removed; use checkredlinks=true in [[Modül:başlık başı]]") end terms.label = export.replace_glossary_links_in_label(label) if data.accel then terms.accel = data.accel end terms.enable_auto_translit = data.enable_auto_translit inflobj.inflections = inflobj.inflections or {} insert(inflobj.inflections, terms) elseif data.request then inflobj.inflections = inflobj.inflections or {} insert(inflobj.inflections, { label = export.replace_glossary_links_in_label(label), request = true, }) end end --[==[ Parse raw arguments from `forms` for inline modifiers, and insert the resulting terms (which should not require significant additional processing) into `headdata.inflections`. `data` is an object with the following fields: * `forms`: The list of raw values to parse. If {nil} or omitted, nothing happens. * `headdata`: The headword structure passed to [[Modül:başlık başı]]. Required. * `paramname`: As in `parse_term_list_with_modifiers()`. Required. * `label`: As in `insert_inflection()`. Required. * `qualifiers`, `frob`, `include_mods`, `exclude_mods`, `is_head`, `splitchar`, `preserve_splitchar`, `delimiter_key`, `escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_term_list_with_modifiers()`. * `accel`: As in `insert_inflection()`. ]==] function export.parse_and_insert_inflection(data) local forms = data.forms if forms and forms[1] then data = shallow_copy(data) data.forms = forms data.terms = export.parse_term_list_with_modifiers(data) export.insert_inflection(data) end end --[==[ Combine two sets of qualifiers or labels. If either is {nil}, just return the other, and if both are {nil}, return {nil}. ]==] function export.combine_qualifiers_or_labels(quals1, quals2) if not quals1 and not quals2 then return nil end if not quals1 then return quals2 end if not quals2 then return quals1 end local combined = shallow_copy(quals1) for _, note in ipairs(quals2) do insert_if_not(combined, note) end return combined end --[==[ Combine the qualifiers, labels, references and ID's of two term objects. `destobj` is the "destination term object" into which the combined properties are written, and `srcobj` is the "source object" into which the properties are merged. `destobj` is side-effected (but the lists inside of `destobj` are not); if this is undesirable, make sure to shallow-copy `destobj` first. If both objects have values for a given qualifier, label or reference, the values of `destobj` come first. If both objects have a value for `id`, the values must match or an error is thrown; otherwise, the resulting value of `id` comes from whichever one is defined. '''NOTE:''' This may not be the correct behavior when deduplicating a list of term objects. See `insert_termobj_combining_duplicates` for a different approach. ]==] function export.combine_termobj_qualifiers_labels(destobj, srcobj) destobj.q = export.combine_qualifiers_or_labels(destobj.q, srcobj.q) destobj.qq = export.combine_qualifiers_or_labels(destobj.qq, srcobj.qq) destobj.l = export.combine_qualifiers_or_labels(destobj.l, srcobj.l) destobj.ll = export.combine_qualifiers_or_labels(destobj.ll, srcobj.ll) destobj.refs = export.combine_qualifiers_or_labels(destobj.refs, srcobj.refs) if destobj.id and srcobj.id and destobj.id ~= srcobj.id then -- FIXME: We probably want to pass in an error function error(("Can't specify two different ID's %s and %s when combining objects"):format(srcobj.id, destobj.id)) end destobj.id = destobj.id or srcobj.id return destobj end function export.termobj_has_qualifiers_or_labels(obj) return obj.q and obj.q[1] or obj.qq and obj.qq[1] or obj.l and obj.l[1] or obj.ll and obj.ll[1] or obj.refs and obj.refs[1] end local function one_ancillary_property_equal(prop1, prop2) local prop1_is_nil = not prop1 or not prop1[1] local prop2_is_nil = not prop2 or not prop2[1] if prop1_is_nil and prop2_is_nil then return true end if prop1_is_nil or prop2_is_nil then return false end return deepEquals(prop1, prop2) end function export.termobj_ancillary_properties_equal(obj1, obj2) return one_ancillary_property_equal(obj1.q, obj2.q) and one_ancillary_property_equal(obj1.qq, obj2.qq) and one_ancillary_property_equal(obj1.l, obj2.l) and one_ancillary_property_equal(obj1.ll, obj2.ll) and one_ancillary_property_equal(obj1.refs, obj2.refs) and obj1.id == obj2.id end function export.convert_termobj_to_formobj(termobj) local formobj = { form = termobj.term, translit = termobj.tr, } local footnotes local function mods_to_footnote(mod_prefix, mod_vals) if mod_vals and mod_vals[1] then footnotes = footnotes or {} for _, val in ipairs(mod_vals) do insert(footnotes, "[" .. mod_prefix .. ":" .. val .. "]") end end end mods_to_footnote("q", termobj.q) mods_to_footnote("qq", termobj.qq) mods_to_footnote("l", termobj.l) mods_to_footnote("ll", termobj.ll) mods_to_footnote("ref", termobj.refs) mods_to_footnote("id", termobj.id and {termobj.id} or nil) formobj.footnotes = footnotes return formobj end local recognized_multi_mods = { q = "q", qq = "qq", l = "l", ll = "ll", ref = "refs", } local recognized_single_mods = { id = "id", } function export.add_footnote_to_termobj(termobj, footnote) local stripped_footnote = footnote:match("^%[(.*)%]$") if not stripped_footnote then error("Internal error: Footnote should be surrounded by brackets at this stage: " .. footnote) end local prefix, rest = stripped_footnote:match("^([a-z]+):(.+)$") local field, is_multi if prefix then if recognized_multi_mods[prefix] then field = recognized_multi_mods[prefix] is_multi = true elseif recognized_single_mods[prefix] then field = recognized_single_mods[prefix] is_multi = false end end if not field then rest = stripped_footnote field = "l" is_multi = true end if is_multi then if not termobj[field] then termobj[field] = {} end insert(termobj[field], rest) else if termobj[field] and termobj[field] ~= rest then error(("Can't set two values for '%s': '%s' and '%s'"):format(field, termobj[field], rest)) end termobj[field] = rest end end function export.convert_formobj_to_termobj(formobj) local termobj = { term = formobj.form, tr = formobj.translit, } if formobj.footnotes then for _, footnote in ipairs(formobj.footnotes) do export.add_footnote_to_termobj(termobj, footnote) end end return termobj end local function extract_termobj_field_modifiers(fieldval) return fieldval:match("^([*+]?)(.*)$") end function export.remove_termobj_field_modifiers(termobj) local function remove_field_modifiers(field) if termobj[field] and termobj[field][1] then local any_field_modifiers = false for _, val in ipairs(termobj[field]) do local field_mods, _ = extract_termobj_field_modifiers(val) if field_mods ~= "" then any_field_modifiers = true break end end local new_field = {} if any_field_modifiers then for _, val in ipairs(termobj[field]) do local _, field_without_mods = extract_termobj_field_modifiers(val) insert_if_not(new_field, field_without_mods) end termobj[field] = new_field end end end remove_field_modifiers("q") remove_field_modifiers("qq") remove_field_modifiers("l") remove_field_modifiers("ll") remove_field_modifiers("refs") end function export.insert_termobj_combining_duplicates(destobjs, termobj) for _, destobj in ipairs(destobjs) do if destobj.term == termobj.term and destobj.tr == termobj.tr then -- Form already present; maybe combine footnotes. local function combine_field_values(field) if termobj[field] and termobj[field][1] then -- Check to see if there are existing values with *; if so, remove them. if destobj[field] and destobj[field][1] then local any_values_with_asterisk = false for _, val in ipairs(destobj[field]) do local field_mods, _ = extract_termobj_field_modifiers(val) if field_mods:find("%*") then any_values_with_asterisk = true break end end if any_values_with_asterisk then local filtered_values = {} for _, val in ipairs(destobj[field]) do local field_mods, _ = extract_termobj_field_modifiers(val) if not val:find("%*") then insert(filtered_values, val) end end if filtered_values[1] then destobj[field] = filtered_values else destobj[field] = nil end end end local any_values_with_plus = false for _, val in ipairs(termobj[field]) do local field_mods, _ = extract_termobj_field_modifiers(val) if val:find("%+") then any_footnotes_with_plus = true break end end if any_footnotes_with_plus then if not destobj[field] then destobj[field] = {} else destobj[field] = shallow_copy(destobj[field]) end for _, val in ipairs(termobj[field]) do local already_seen = false local field_mods, field_without_mods = extract_termobj_field_modifiers(val) if val:find("%+") then for _, existing_val in ipairs(destobj[field]) do local existing_field_mods, existing_field_without_mods = extract_termobj_field_modifiers(existing_val) if existing_field_without_mods == field_without_mods then already_seen = true break end end if not already_seen then insert(destobj[field], val) end end end end end end combine_field_values("q") combine_field_values("qq") combine_field_values("l") combine_field_values("ll") combine_field_values("refs") if destobj.id and termobj.id and destobj.id ~= termobj.id then -- FIXME: We probably want to pass in an error function error(("Can't specify two different ID's %s and %s when combining objects"):format(termobj.id, destobj.id)) end destobj.id = destobj.id or termobj.id return end end insert(destobjs, termobj) end export.allowed_special_indicators = { ["first"] = true, ["first-second"] = true, ["first-last"] = true, ["second"] = true, ["last"] = true, ["each"] = true, ["+"] = true, -- requests the default behavior with preposition handling } --[==[ Check for special indicators (values such as {"+first"} or {"+first-last"} that are used in a `pl`, `f`, etc. argument and indicate how to inflect a multiword term). If `form` is such an indicator, the return value is `form` minus the initial `+` sign; otherwise, if form begins with a `+` sign, an error is thrown; otherwise the return value is nil. ]==] function export.get_special_indicator(form, noerror) if form:find("^%+") then form = form:gsub("^%+", "") if not export.allowed_special_indicators[form] then if noerror then return nil end local indicators = {} for indic, _ in pairs(export.allowed_special_indicators) do insert(indicators, "+" .. indic) end sort(indicators) error("Special inflection indicator beginning with '+' can only be " .. mw.text.listToText(indicators) .. ": +" .. form) end return form end return nil end local function add_endings(bases, endings) local retval = {} if type(bases) ~= "table" then bases = {bases} end if type(endings) ~= "table" then endings = {endings} end for _, base in ipairs(bases) do for _, ending in ipairs(endings) do insert(retval, base .. ending) end end return retval end --[==[ Inflect a possibly multiword or hyphenated term `form` using the function `inflect`, which is a function of one argument that is called on a single word to inflect and should return either the inflected word or a list of inflected words. `special` indicates how to inflect the multiword term and should be e.g. {"first"} to inflect only the first word, {"first-last"} to inflect the first and last words, {"each"} to inflect each word, etc. See `allowed_special_indicators` above for the possibilities. If `special` is `+`, or is omitted and the term is multiword (i.e. containing a space character), and `prepositions` is supplied, the function checks for multiword or hyphenated terms containing the prepositions in `prepositions`, e.g. Italian [[senso di marcia]] or [[medaglia d'oro]] or Portuguese [[tartaruga-do-mar]]. If such a term is found, only the first word is inflected. Otherwise, the default is {"first-last"}. `prepositions` is a list of Lua patterns matching prepositions. The patterns will automatically have the separator character (space or hyphen) added to the left side but not the right side, so they should contain a space character (which will automatically be converted to the appropriate separator) on the right side unless the preposition is joined on the right side with an apostrophe. Examples of preposition patterns for Italian are {"di "}, {"sull'"} and {"d?all[oae] "} (which matches {"dallo "}, {"dalle "}, {"alla "}, etc.). The return value is always either a list of inflected multiword or hyphenated terms, or nil if `special` is omitted and `form` is not multiword. (If `special` is specified and `form` is not multiword or hyphenated, an error results.) ]==] function export.handle_multiword(form, special, inflect, prepositions, sep) sep = sep or form:find(" ") and " " or "%-" local raw_sep = sep == " " and " " or "-" -- Used to add regex version of separator in the replacement portion of ugsub() or :gsub() local sep_replacement = sep == " " and " " or "%%-" -- Given a Lua pattern, replace space with the appropriate separator. local function hack_re(re) if sep == " " then return re end return (re:gsub(" ", sep_replacement)) end if special == "first" then local first, rest = form:match(hack_re("^(.-)( .*)$")) if not first then error("Special indicator 'first' can only be used with a multiword term: " .. form) end return add_endings(inflect(first), rest) elseif special == "second" then local first, second, rest = form:match(hack_re("^([^ ]+ )([^ ]+)( .*)$")) if not first then error("Special indicator 'second' can only be used with a term with three or more words: " .. form) end return add_endings(add_endings({first}, inflect(second)), rest) elseif special == "first-second" then local first, space, second, rest = form:match(hack_re("^([^ ]+)( )([^ ]+)( .*)$")) if not first then error("Special indicator 'first-second' can only be used with a term with three or more words: " .. form) end return add_endings(add_endings(add_endings(inflect(first), space), inflect(second)), rest) elseif special == "each" then local terms = split(form, sep) if #terms < 2 then error("Special indicator 'each' can only be used with a multiword term: " .. form) end for i, term in ipairs(terms) do terms[i] = inflect(term) if i > 1 then terms[i] = add_endings(raw_sep, terms[i]) end end local result = "" for _, term in ipairs(terms) do result = add_endings(result, term) end return result elseif special == "first-last" then local first, middle, last = form:match(hack_re("^(.-)( .* )(.-)$")) if not first then first, middle, last = form:match(hack_re("^(.-)( )(.*)$")) end if not first then error("Special indicator 'first-last' can only be used with a multiword term: " .. form) end return add_endings(add_endings(inflect(first), middle), inflect(last)) elseif special == "last" then local rest, last = form:match(hack_re("^(.* )(.-)$")) if not rest then error("Special indicator 'last' can only be used with a multiword term: " .. form) end return add_endings(rest, inflect(last)) elseif special and special ~= "+" then error("Unrecognized special=" .. special) end -- Only do default behavior if special indicator '+' explicitly given or separator is space; otherwise we will -- break existing behavior with hyphenated words. if (special == "+" or sep == " ") and form:find(sep) then if prepositions then -- check for prepositions in the middle of the word; do it this way so we can handle -- more than one word before the preposition (and usually inflect each word) for _, prep in ipairs(prepositions) do local first, space_prep_rest = umatch(form, hack_re("^(.-)( " .. prep .. ".*)$")) if first then return add_endings(inflect(first), space_prep_rest) end end end -- multiword or hyphenated expressions default to first-last; we need to pass in the separator to avoid -- problems with multiword terms containing hyphens in the individual words return export.handle_multiword(form, "first-last", inflect, prepositions, sep) end return nil end local function link_hyphen_split_component(word, data) if data.link_hyphen_split_component then return data.link_hyphen_split_component(word) else return "[[" .. word .. "]]" end end -- Default function to split a word on apostrophes. Don't split apostrophes at the beginning or end of a word (e.g. -- [['ndrangheta]] or [[po']]). Handle multiple apostrophes correctly, e.g. [[l'altr'ieri]] -> [[l']][altr']][[ieri]]. function export.default_split_apostrophe(word, data) local apostrophe_parts = split(word, "'", true, true) local linked_apostrophe_parts = {} local apostrophes_at_beginning = "" local i = 1 -- Apostrophes at beginning get attached to the first word after (which will always exist but may -- be blank if the word consists only of apostrophes). while i < #apostrophe_parts do -- <, not <=, in case the word consists only of apostrophes local apostrophe_part = apostrophe_parts[i] i = i + 1 if apostrophe_part == "" then apostrophes_at_beginning = apostrophes_at_beginning .. "'" else break end end apostrophe_parts[i] = apostrophes_at_beginning .. apostrophe_parts[i] -- Now, do the remaining parts. A blank part indicates more than one apostrophe in a row; we join -- all of them to the preceding word. while i <= #apostrophe_parts do local apostrophe_part = apostrophe_parts[i] if apostrophe_part == "" then linked_apostrophe_parts[#linked_apostrophe_parts] = linked_apostrophe_parts[#linked_apostrophe_parts] .. "'" elseif i == #apostrophe_parts then insert(linked_apostrophe_parts, apostrophe_part) else insert(linked_apostrophe_parts, apostrophe_part .. "'") end i = i + 1 end for j, tolink in ipairs(linked_apostrophe_parts) do linked_apostrophe_parts[j] = link_hyphen_split_component(tolink, data) end return concat(linked_apostrophe_parts) end --[=[ Auto-add links to a word that should not have spaces but may have hyphens and/or apostrophes. We split off final punctuation, then split on hyphens if `data.split_hyphen` is given, and also split on apostrophes if `data.split_apostrophe` is given. We only split on hyphens if they are in the middle of the word, not at the beginning or end (hyphens at the beginning or end indicate suffixes or prefixes, respectively). `include_hyphen_prefixes`, if given, is a set of prefixes (not including the final hyphen) where we should include the final hyphen in the prefix. Hence, e.g. if "anti" is in the set, a Portuguese word like [[anti-herói]] "anti-hero" will be split [[anti-]][[herói]] (whereas a word like [[código-fonte]] "source code" will be split as [[código]]-[[fonte]]). If `data.split_apostrophe` is specified, we split on apostrophes unless `data.no_split_apostrophe_words` is given and the word is in the specified set, such as French [[c'est]] and [[quelqu'un]]. If `data.split_apostrophe` is true, the default algorithm applies, which splits on all apostrophes except those at the beginning and end of a word (as in Italian [['ndrangheta]] or [[po']]), and includes the apostrophe in the link to its left (so we auto-split French [[l'eau]] as [[l']][[eau]] and [[l'altr'ieri]] as [[l']][altr']][[ieri]]). If `data.split_apostrophe` is specified but not `true`, it should be a function of one argument that does custom apostrophe-splitting. The argument is the word to split, and the return value should be the split and linked word. ]=] local function add_single_word_links(space_word, data, term_has_spaces) local space_word_no_punct, punct local punct_pattern = data.punctuation if punct_pattern and is_callable(punct_pattern) then space_word_no_punct, punct = punct_pattern(space_word) else if punct_pattern == nil then punct_pattern = "[,;:?!]" end space_word_no_punct, punct = umatch(space_word, "^(.*)(" .. punct_pattern .. ")$") end space_word_no_punct = space_word_no_punct or space_word punct = punct or "" local words if space_word_no_punct:sub(1, 1) == "-" or space_word_no_punct:sub(-1) == "-" then -- don't split prefixes and suffixes words = {space_word_no_punct} else local splitter if term_has_spaces then splitter = data.split_hyphen_when_space else splitter = data.split_hyphen_when_no_space end if is_callable(splitter) then words = splitter(space_word_no_punct) if type(words) == "string" then return words .. punct end end end if not words then local split_hyphen if term_has_spaces then split_hyphen = data.split_hyphen_when_space else split_hyphen = data.split_hyphen_when_no_space if split_hyphen == nil then -- default to true; use `false` to avoid this split_hyphen = true end end if split_hyphen then words = split(space_word_no_punct, "-", true, true) else words = {space_word_no_punct} end end local linked_words = {} for j, word in ipairs(words) do if j < #words and data.include_hyphen_prefixes and data.include_hyphen_prefixes[word] then word = "[[" .. word .. "-]]" elseif j > 1 and data.include_hyphen_suffixes and data.include_hyphen_suffixes[word] then word = "[[-" .. word .. "]]" else -- Don't split on apostrophes if the word is in `no_split_apostrophe_words`. if (not data.no_split_apostrophe_words or not data.no_split_apostrophe_words[word]) and data.split_apostrophe and word:find("'", nil, true) then if data.split_apostrophe == true then word = export.default_split_apostrophe(word, data) else -- custom apostrophe splitter/linker word = data.split_apostrophe(word) end elseif word ~= "" then -- avoid -[[]]- (e.g. f--k) word = link_hyphen_split_component(word, data) end if j < #words then word = word .. "-" end end insert(linked_words, word) end return concat(linked_words) .. punct end --[=[ Auto-add links to a multiword term. `data` contains fields customizing how to do this. By default we proceed as follows: (1) If the term already has embedded links in it, they are left unchanged. (2) Otherwise, if there are spaces present, we split on spaces and link each word separately. (3) If a given space-separated component ends in punctuation (defaulting to [,;:?!]), it is separated off, the remainder of the algorithm run, and the punctuation pasted back on. (4) If there are hyphens in a given space-separated component, we may link each hyphenated term separately depending on the settings in `data`. Normally the hyphens are not included in the linked terms, but this can be overridden for specific prefixes and/or suffixes. By default, if there are spaces in the multiword term, we do not link hyphenated components (because of cases like "boire du petit-lait" where "petit-lait" should be linked as a whole), but do so otherwise (e.g. for "avant-avant-hier"); this can overridden for cases like "croyez-le ou non". Cases where only some of the hyphens should be split can always be handled by explicitly specifying the head (e.g. "Nord-Pas-de-Calais" given as head=[[Nord]]-[[Pas-de-Calais]]). (5) If there are apostrophes in a given component, we may link each apostrophe-separated term separately depending on the settings in `data`, including the apostrophe in the link to its left (so we split "de l'eau" as "[[de]] [[l']][[eau]]"). The settings in `data` are as follows: `split_hyphen_when_no_space`: Whether to split on hyphens when the term has no spaces. Defaults to true if set to `nil`. This can be a function of one argument, to implement a custom splitting algorithm for hyphen-separated terms. If this returns [FIXME: FINISH ME ...] If `data.split_apostrophe` is specified, we split on apostrophes unless `data.no_split_apostrophe_words` is given and the word is in the specified set, such as French [[c'est]] and [[quelqu'un]]. If `data.split_apostrophe` is true, the default algorithm applies, which splits on all apostrophes except those at the beginning and end of a word (as in Italian [['ndrangheta]] or [[po']]), and includes the apostrophe in the link to its left (so we auto-split French [[l'eau]] as [[l']][[eau]] and [[l'altr'ieri]] as [[l']][altr']][[ieri]]). If `data.split_apostrophe` is specified but not `true`, it should be a function of one argument that does custom apostrophe-splitting. The argument is the word to split, and the return value should be the split and linked word. We don't always split on hyphens because of cases like "boire du petit-lait" where "petit-lait" should be linked as a whole, but provide the option to do it for cases like "croyez-le ou non". If there's no space, however, then it makes sense to split on hyphens by `no_split_apostrophe_words` and `include_hyphen_prefixes` allow for special-case handling of particular words and are as described in the comment above add_single_word_links(). ]=] function export.add_links_to_multiword_term(term, data) if term:match("[%[%]]") then return term end local words = split(term, " ", true, true) local term_has_spaces = #words > 1 local linked_words = {} for _, word in ipairs(words) do insert(linked_words, add_single_word_links(word, data, term_has_spaces)) end local retval = concat(linked_words, " ") -- If we ended up with a single link consisting of the entire term, -- remove the link. return retval:match("^%[%[([^%[%]]*)%]%]$") or retval end local function canonicalize_begin_end_spec(spec) local from, to = spec:match("^(.-):(.*)$") if not from then from = spec to = "" end return from, to end --[==[ Given a `linked_term` that is the output of add_links_to_multiword_term(), apply modifications as given in `modifier_spec` to change the link destination of subterms (normally single-word non-lemma forms; sometimes collections of adjacent words). This is usually used to link non-lemma forms to their corresponding lemma, but can also be used to replace a span of adjacent separately-linked words to a single multiword lemma. The format of `modifier_spec` is one or more semicolon-separated subterm specs, where each such spec is of the form SUBTERM:DEST, where SUBTERM is one or more words in the `linked_term` but without brackets in them, and DEST is the corresponding link destination to link the subterm to. Any occurrence of ~ in DEST is replaced with SUBTERM. Alternatively, a single modifier spec can be of the form BEGIN[FROM:TO], which is equivalent to writing BEGINFROM:BEGINTO (see example below). For example, given the source phrase [[il bue che dice cornuto all'asino]] "the pot calling the kettle black" (literally "the ox that calls the donkey horned/cuckolded"), the result of calling add_links_to_multiword_term() is [[il]] [[bue]] [[che]] [[dice]] [[cornuto]] [[all']][[asino]]. With a modifier_spec of 'dice:dire', the result is [[il]] [[bue]] [[che]] [[dire|dice]] [[cornuto]] [[all']][[asino]]. Here, based on the modifier spec, the non-lemma form [[dice]] is replaced with the two-part link [[dire|dice]]. Another example: given the source phrase [[chi semina vento raccoglie tempesta]] "sow the wind, reap the whirlwind" (literally (he) who sows wind gathers [the] tempest"). The result of calling add_links_to_multiword_term() is [[chi]] [[semina]] [[vento]] [[raccoglie]] [[tempesta]], and with a modifier_spec of 'semina:~re; raccoglie:~re', the result is [[chi]] [[seminare|semina]] [[vento]] [[raccogliere|raccoglie]] [[tempesta]]. Here we use the ~ notation to stand for the non-lemma form in the destination link. A more complex example is [[se non hai altri moccoli puoi andare a letto al buio]], which becomes [[se]] [[non]] [[hai]] [[altri]] [[moccoli]] [[puoi]] [[andare]] [[a]] [[letto]] [[al]] [[buio]] after calling add_links_to_multiword_term(). With the following modifier_spec: 'hai:avere; altr[i:o]; moccol[i:o]; puoi: potere; andare a letto:~; al buio:~', the result of applying the spec is [[se]] [[non]] [[avere|hai]] [[altro|altri]] [[moccolo|moccoli]] [[potere|puoi]] [[andare a letto]] [[al buio]]. Here, we rely on the alternative notation mentioned above for e.g. 'altr[i:o]', which is equivalent to 'altri:altro', and link multiword subterms using e.g. 'andare a letto:~'. (The code knows how to handle multiword subexpressions properly, and if the link text and destination are the same, only a single-part link is formed.) ]==] function export.apply_link_modifiers(linked_term, modifier_spec, lang) local split_modspecs = split(modifier_spec, "%s*;%s*") for j, modspec in ipairs(split_modspecs) do local id if modspec:find("<") then local rest rest, id = modspec:match("^(.*)<id:(.-)>$") if rest then modspec = rest end end local subterm, dest, otherlang local begin_spec, rest, end_spec = modspec:match("^%[(.-)%]([^:]*)%[(.-)%]$") if begin_spec then local begin_from, begin_to = canonicalize_begin_end_spec(begin_spec) local end_from, end_to = canonicalize_begin_end_spec(end_spec) subterm = begin_from .. rest .. end_from dest = begin_to .. rest .. end_to end if not subterm then rest, end_spec = modspec:match("^([^:]*)%[(.-)%]$") if rest then local end_from, end_to = canonicalize_begin_end_spec(end_spec) subterm = rest .. end_from dest = rest .. end_to end end if not subterm then begin_spec, rest = modspec:match("^%[(.-)%]([^:]*)$") if begin_spec then local begin_from, begin_to = canonicalize_begin_end_spec(begin_spec) subterm = begin_from .. rest dest = begin_to .. rest end end if not subterm then subterm, dest = modspec:match("^(.-)%s*:%s*(.*)$") if subterm and subterm ~= "^" and subterm ~= "$" then local langdest -- Parse off an initial language code (e.g. 'en:Higgs', 'la:minūtia' or 'grc:σκατός'). Also handle -- Wikipedia prefixes ('w:Abatemarco' or 'w:it:Colle Val d'Elsa'). otherlang, langdest = dest:match("^([A-Za-z0-9._-]+):([^ ].*)$") if otherlang == "w" then local foreign_wikipedia, foreign_term = langdest:match("^([A-Za-z0-9._-]+):([^ ].*)$") if foreign_wikipedia then otherlang = otherlang .. ":" .. foreign_wikipedia langdest = foreign_term end dest = ("%s:%s"):format(otherlang, langdest) otherlang = nil elseif otherlang then otherlang = get_lang(otherlang, true, "allow etym") dest = langdest end end end if not subterm then if modspec == "?" or modspec == "!" then subterm = "$" dest = modspec elseif modspec == "..." or modspec == "...?" then subterm = "$" dest = " " .. modspec elseif modspec:find("^[A-Z]$") then -- X, Y, etc. by themselves are unlinked, to help with snowclones subterm = modspec dest = "_" else subterm = modspec dest = "~" end end if subterm == "^" then linked_term = dest:gsub("_", " ") .. linked_term elseif subterm == "$" then linked_term = linked_term .. dest:gsub("_", " ") else if subterm:find("[", nil, true) then error(("Subterm '%s' in modifier spec '%s' cannot have brackets in it"):format( escape_wikicode(subterm), escape_wikicode(modspec))) end local escaped_subterm = pattern_escape(subterm) local subterm_re = "%[%[" .. escaped_subterm:gsub("(%%?[ ',%-])", "%%]*%1%%[*") .. "%]%]" local expanded_dest if dest:find("~", nil, true) then expanded_dest = dest:gsub("~", replacement_escape(subterm)) else expanded_dest = dest end if otherlang then expanded_dest = expanded_dest .. "#" .. otherlang:getCanonicalName() end local subterm_replacement if expanded_dest == "_" then subterm_replacement = subterm if id then error("Can't supply <id:...> with an unlinked subterm") end if otherlang then error("Can't supply prefixed language with an unlinked subterm") end elseif id or otherlang then if id and expanded_dest:find("[", nil, true) then error("Can't supply <id:...> with destination with embedded brackets") end subterm_replacement = require(links_module).language_link { lang = otherlang or lang, term = expanded_dest, alt = subterm, id = id, } elseif expanded_dest:find("[", nil, true) then -- Use the destination directly if it has brackets in it (e.g. to put brackets around parts of a word). subterm_replacement = expanded_dest elseif expanded_dest == subterm then subterm_replacement = "[[" .. subterm .. "]]" else subterm_replacement = "[[" .. expanded_dest .. "|" .. subterm .. "]]" end local escaped_subterm_replacement = replacement_escape(subterm_replacement) local replaced_linked_term = ugsub(linked_term, subterm_re, escaped_subterm_replacement) if replaced_linked_term == linked_term then mw.log(("Attempted to replace %s with %s in %s"):format(subterm_re, escaped_subterm_replacement, linked_term)) error(("Subterm '%s' could not be located in %slinked expression %s, or replacement same as subterm"):format( subterm, j > 1 and "intermediate " or "", escape_wikicode(linked_term))) else linked_term = replaced_linked_term end end end return linked_term end return export adi8s3uo39xiyojd8a3chek0hzlgl25 аббревиировать 0 1591015 5672515 2026-06-29T18:50:00Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|аббревии́ровать|impf|pf=проаббревии́ровать}} # [[kısaltmak]] 5672515 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|аббревии́ровать|impf|pf=проаббревии́ровать}} # [[kısaltmak]] ix0ip185fbbqpctegu4vhwcjoctw95f проаббревиировать 0 1591016 5672516 2026-06-29T18:50:39Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|проаббревии́ровать|pf|impf=аббревии́ровать}} # [[kısaltmak]] 5672516 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|проаббревии́ровать|pf|impf=аббревии́ровать}} # [[kısaltmak]] fyweijwxza2fqlwjmim9e6kic430g39 аблактировать 0 1591017 5672517 2026-06-29T18:51:44Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|аблакти́ровать|impf}} # [[sütten kesmek]] 5672517 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|аблакти́ровать|impf}} # [[sütten kesmek]] fqi3hgq80svvrw785puq6f1g641ker7 ana mektebi 0 1591018 5672521 2026-06-29T19:04:32Z Satirdan kahraman 37401 Yeni sayfa : ==Türkçe== ===Köken=== * {{birleşik|dil=tr|ana|mektep}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||a|na|mek|te|bi}} ===Ad=== {{tr-ad|istisna=bileşik}} [[File:TR Izmir asv2020-02 img38 Löhner mansion.jpg|küçükresim|Anaokulu]] # {{t|eğitim|dil=tr}} öğrenim çağına henüz gelmemiş 2-6 yaş arasındaki çocukları okul düzenine hazırlayan eğitim kuruluşu; [[ana mektebi]] ====Çekimleme==== {{tr-ad-tablo|istisna=bileşik}} ===Kaynakça=== * {{KYK:TDK}} ===Ek ok... 5672521 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|ana|mektep}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||a|na|mek|te|bi}} ===Ad=== {{tr-ad|istisna=bileşik}} [[File:TR Izmir asv2020-02 img38 Löhner mansion.jpg|küçükresim|Anaokulu]] # {{t|eğitim|dil=tr}} öğrenim çağına henüz gelmemiş 2-6 yaş arasındaki çocukları okul düzenine hazırlayan eğitim kuruluşu; [[ana mektebi]] ====Çekimleme==== {{tr-ad-tablo|istisna=bileşik}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} 100trno6s6yfdw1uh70hlgpr5w62te6 5672522 5672521 2026-06-29T19:04:46Z Satirdan kahraman 37401 /* */ [[MediaWiki:Gadget-AjaxEdit.js|AjaxDüzenle]] kullanılarak değiştirildi 5672522 wikitext text/x-wiki ==Türkçe== ===Köken=== * {{birleşik|dil=tr|ana|mektep}} ===Söyleniş=== * {{tr-IPA}} * {{h|dil=tr||a|na|mek|te|bi}} ===Ad=== {{tr-ad|istisna=bileşik}} [[File:TR Izmir asv2020-02 img38 Löhner mansion.jpg|küçükresim|Bir '''ana mektebi.''']] # {{t|eğitim|dil=tr}} öğrenim çağına henüz gelmemiş 2-6 yaş arasındaki çocukları okul düzenine hazırlayan eğitim kuruluşu; [[ana mektebi]] ====Çekimleme==== {{tr-ad-tablo|istisna=bileşik}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} c50tk9obhemlgfu0wcm4pui2v6ymoza абонироваться 0 1591019 5672532 2026-06-29T19:27:57Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|абони́роваться|impf|c2=pf}} # {{t|dil=ru|eskimiş}} [[abone olmak]] 5672532 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|абони́роваться|impf|c2=pf}} # {{t|dil=ru|eskimiş}} [[abone olmak]] r04zoj9sktw0z48kujqw0z5ih84g763 5672533 5672532 2026-06-29T19:28:10Z MustafaCavlak 59368 /* Eylem */ 5672533 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|абони́роваться|impf-pf}} # {{t|dil=ru|eskimiş}} [[abone olmak]] qsrqmxb9mmysufe9k6mj7f9bdw2wr21 абсолютизировать 0 1591020 5672534 2026-06-29T19:30:25Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|абсолютизи́ровать|impf-pf}} # [[mutlaklaştırmak]], [[mutlak]] hâle getirmek 5672534 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|абсолютизи́ровать|impf-pf}} # [[mutlaklaştırmak]], [[mutlak]] hâle getirmek 24v4tx3ppqhnmik4bpq4quzsxhqh3kg абсорбировать 0 1591021 5672537 2026-06-29T19:32:05Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|абсорби́ровать|impf-pf}} # [[soğurmak]], [[absorbe etmek]] 5672537 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|абсорби́ровать|impf-pf}} # [[soğurmak]], [[absorbe etmek]] tjb6x89krlrmwz5m7oipapdwi7btqdo абсорбироваться 0 1591022 5672539 2026-06-29T19:34:26Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|абсорби́роваться|impf-pf}} # {{çekim|dil=ru|абсорби́ровать||pass}}: [[soğrulmak]], [[absorbe]] edilmek 5672539 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|абсорби́роваться|impf-pf}} # {{çekim|dil=ru|абсорби́ровать||pass}}: [[soğrulmak]], [[absorbe]] edilmek 0l0t8ipig74iw9trz16askgvn54nvwi yorumlatmak 0 1591023 5672540 2026-06-29T19:35:18Z Satirdan kahraman 37401 Yeni sayfa : ==Türkçe== ===Köken=== ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||yo|rum|lat|mak}} ===Eylem=== {{tr-eylem}} [[File:Olaus Magnus - On the Art of Prophecy.jpg|thumb|Kral, adama ölü balıkların ne anlama geldiğini '''yorumlatıyor.''']] # [[yorumlama|Yorumlama]] işini yaptırmak. ====Çekimleme==== {{tr-eylem-tablo}} ===Kaynakça=== * {{KYK:TDK}} 5672540 wikitext text/x-wiki ==Türkçe== ===Köken=== ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||yo|rum|lat|mak}} ===Eylem=== {{tr-eylem}} [[File:Olaus Magnus - On the Art of Prophecy.jpg|thumb|Kral, adama ölü balıkların ne anlama geldiğini '''yorumlatıyor.''']] # [[yorumlama|Yorumlama]] işini yaptırmak. ====Çekimleme==== {{tr-eylem-tablo}} ===Kaynakça=== * {{KYK:TDK}} nzc303kebhdbrh8o4jhkwt8anlqa53i абстрагировать 0 1591024 5672541 2026-06-29T19:35:39Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|абстраги́ровать|impf-pf}} # [[soyutlaştırmak]] 5672541 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|абстраги́ровать|impf-pf}} # [[soyutlaştırmak]] hsiq1izurx9bb85944eenyn1d27494l абьюзить 0 1591025 5672543 2026-06-29T19:37:59Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|абью́зить|impf|pf=заабью́зить}} # {{t|dil=ru|argo}} [[istismar etmek]] 5672543 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|абью́зить|impf|pf=заабью́зить}} # {{t|dil=ru|argo}} [[istismar etmek]] 970et3b41s5cc645ukpd2bahuqn97jw Kategori:Rusça argo 14 1591026 5672544 2026-06-29T19:38:30Z MustafaCavlak 59368 Yeni sayfa : {{kategori söz|dil=ru|söz=argo}} 5672544 wikitext text/x-wiki {{kategori söz|dil=ru|söz=argo}} kj1hv0w49bh8u2f8513j0yzxt6x5gsw заабьюзить 0 1591027 5672545 2026-06-29T19:39:51Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|заабью́зить|pf|impf=абью́зить}} # {{t|dil=ru|argo}} [[istismar etmek]] 5672545 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|заабью́зить|pf|impf=абью́зить}} # {{t|dil=ru|argo}} [[istismar etmek]] c7uhr502q5fhc69xc1gulyn05y7o5ev авансировать 0 1591028 5672546 2026-06-29T19:42:01Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|аванси́ровать|impf-pf}} # [[avans vermek]] 5672546 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|аванси́ровать|impf-pf}} # [[avans vermek]] 0f6s3k9jgdtex4v7hi5pq6rbbleovu5 автоматизировать 0 1591029 5672548 2026-06-29T19:44:28Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|автоматизи́ровать|impf-pf}} # [[otomatikleştirmek]], [[otomatik]] hâle getirmek 5672548 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|автоматизи́ровать|impf-pf}} # [[otomatikleştirmek]], [[otomatik]] hâle getirmek 0bylxohkbsyafqgbwgeb59dz06gqap4 авторизовать 0 1591030 5672549 2026-06-29T19:46:39Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|авторизова́ть|impf-pf|impf=авторизо́вывать}} # [[yetkilendirmek]], [[yetki vermek]] 5672549 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|авторизова́ть|impf-pf|impf=авторизо́вывать}} # [[yetkilendirmek]], [[yetki vermek]] dd6sirs58cwtmsyva79nftw7rialf0m Kategori:Rusçada binalar 14 1591031 5672562 2026-06-29T20:41:22Z MustafaCavlak 59368 Yeni sayfa : {{kategori konu|dil=ru|konu=binalar}} 5672562 wikitext text/x-wiki {{kategori konu|dil=ru|konu=binalar}} j89plyu4suf45kekvtxmm75yzqeqh71 театры 0 1591032 5672563 2026-06-29T20:43:32Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тры}} # {{çekim|dil=ru|теа́тр||nom//acc|ç}} 5672563 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тры}} # {{çekim|dil=ru|теа́тр||nom//acc|ç}} 2fhk497vt69nmxiwmvkjq7gpt4sjszf театра 0 1591033 5672564 2026-06-29T20:44:32Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тра}} # {{çekim|dil=ru|теа́тр||gen|t}} 5672564 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тра}} # {{çekim|dil=ru|теа́тр||gen|t}} hisy27ustzqf84kx180kl068mfdlbk2 театров 0 1591034 5672565 2026-06-29T20:45:27Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тров}} # {{çekim|dil=ru|теа́тр||gen|ç}} 5672565 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тров}} # {{çekim|dil=ru|теа́тр||gen|ç}} 9u8doar847611s8oxrep5hdyudxgybs театру 0 1591035 5672566 2026-06-29T20:46:06Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тру}} # {{çekim|dil=ru|теа́тр||dat|t}} 5672566 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тру}} # {{çekim|dil=ru|теа́тр||dat|t}} d47e9nzih3tram6ueilfnn0083763o1 театрам 0 1591036 5672567 2026-06-29T20:46:38Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́трам}} # {{çekim|dil=ru|теа́тр||dat|ç}} 5672567 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́трам}} # {{çekim|dil=ru|теа́тр||dat|ç}} rcbqon3o3shs71nvq6nm7u5kjzptr43 театром 0 1591037 5672568 2026-06-29T20:47:10Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тром}} # {{çekim|dil=ru|теа́тр||araç|t}} 5672568 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тром}} # {{çekim|dil=ru|теа́тр||araç|t}} 87se4hs5g4e4c6qvzxfnjiml3im39wu театрами 0 1591038 5672569 2026-06-29T20:47:44Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́трами}} # {{çekim|dil=ru|теа́тр||araç|ç}} 5672569 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́трами}} # {{çekim|dil=ru|теа́тр||araç|ç}} 3y5oq4v8ml2pxtxlo8hprohizsb63kf театре 0 1591039 5672571 2026-06-29T20:48:13Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тре}} # {{çekim|dil=ru|теа́тр||ilgeç|t}} 5672571 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́тре}} # {{çekim|dil=ru|теа́тр||ilgeç|t}} 6emtmae13ghg1jgww2pavjfnh3chsq1 театрах 0 1591040 5672573 2026-06-29T20:48:43Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́трах}} # {{çekim|dil=ru|теа́тр||ilgeç|ç}} 5672573 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|çekimli ad|baş=теа́трах}} # {{çekim|dil=ru|теа́тр||ilgeç|ç}} 9u3al3sbtpulxmrbhtogiwlrfj32vr1 театральный 0 1591041 5672577 2026-06-29T20:50:10Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ön ad=== {{ru-ön ad|театра́льный}} # [[tiyatral]] 5672577 wikitext text/x-wiki ==Rusça== ===Ön ad=== {{ru-ön ad|театра́льный}} # [[tiyatral]] lyam6jbn367yzpkkruqk1y3qeagl8b1 скорая помощь 0 1591042 5672584 2026-06-29T20:57:48Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|ad|baş=[[скорый|ско́рая]] [[по́мощь]]|c=d}} # [[ambulans]] 5672584 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|ad|baş=[[скорый|ско́рая]] [[по́мощь]]|c=d}} # [[ambulans]] f1x73tqniph0c8wv5ftuwafjz3slc0j γλωσσοδέτης 0 1591043 5672586 2026-06-29T21:02:18Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|e|γλωσσοδέτες}} # [[tekerleme]] ====Çekimleme==== {{el-aE-ης-ες-2b|γλωσσοδέτ|γλωσσοδετ}} 5672586 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|e|γλωσσοδέτες}} # [[tekerleme]] ====Çekimleme==== {{el-aE-ης-ες-2b|γλωσσοδέτ|γλωσσοδετ}} jborxk1mqywu2s2ag76sqkincrkpmx3 скороговорка 0 1591044 5672589 2026-06-29T21:05:12Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ad=== {{başlık başı|ru|ad|baş=скорогово́рка|c=d}} # [[tekerleme]] ====Çekimleme==== {{ru-ad-cansız-d-D-a|скорогово́рка}} 5672589 wikitext text/x-wiki ==Rusça== ===Ad=== {{başlık başı|ru|ad|baş=скорогово́рка|c=d}} # [[tekerleme]] ====Çekimleme==== {{ru-ad-cansız-d-D-a|скорогово́рка}} 4tkkctvurkndqf6ppbweoj1hqi8ll1i говорящий 0 1591045 5672594 2026-06-29T21:16:47Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Ortaç=== {{başlık başı|ru|ortaç|baş=говоря́щий}} # {{çekim|dil=ru|говори́ть||pres|act|tamamlanmamış|part}} 5672594 wikitext text/x-wiki ==Rusça== ===Ortaç=== {{başlık başı|ru|ortaç|baş=говоря́щий}} # {{çekim|dil=ru|говори́ть||pres|act|tamamlanmamış|part}} bygybvov5f19g27r42lnvz0rojv1yeb говорю 0 1591046 5672595 2026-06-29T21:19:00Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=говорю́}} # {{çekim|dil=ru|говори́ть||1t|pres|ind|tamamlanmamış}} 5672595 wikitext text/x-wiki ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=говорю́}} # {{çekim|dil=ru|говори́ть||1t|pres|ind|tamamlanmamış}} 70xy09w2twt5mybeqiwam4skzzd5u52 говоришь 0 1591047 5672596 2026-06-29T21:21:15Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=говори́шь}} # {{çekim|dil=ru|говори́ть||2t|pres|ind|tamamlanmamış}} 5672596 wikitext text/x-wiki ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=говори́шь}} # {{çekim|dil=ru|говори́ть||2t|pres|ind|tamamlanmamış}} 66ihyhwzbvp4lmawfhkaixbohwishs4 буду 0 1591048 5672597 2026-06-29T21:32:22Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́ду}} # {{çekim|dil=ru|быть||1t|fut|ind|tamamlanmamış}} 5672597 wikitext text/x-wiki ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́ду}} # {{çekim|dil=ru|быть||1t|fut|ind|tamamlanmamış}} 72ui8luerk75lctz1gapikk2719gn0q будешь 0 1591049 5672598 2026-06-29T21:33:53Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дешь}} # {{çekim|dil=ru|быть||2t|fut|ind|tamamlanmamış}} 5672598 wikitext text/x-wiki ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дешь}} # {{çekim|dil=ru|быть||2t|fut|ind|tamamlanmamış}} b38zgc1jaenzebrbvp8r2onhksv5evl будет 0 1591050 5672599 2026-06-29T21:35:04Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дет}} # {{çekim|dil=ru|быть||3t|fut|ind|tamamlanmamış}} 5672599 wikitext text/x-wiki ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дет}} # {{çekim|dil=ru|быть||3t|fut|ind|tamamlanmamış}} j8v2ir9xm6qaju0d7wmosprd4mpssnz будем 0 1591051 5672600 2026-06-29T21:36:20Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дем}} # {{çekim|dil=ru|быть||1ç|fut|ind|tamamlanmamış}} 5672600 wikitext text/x-wiki ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дем}} # {{çekim|dil=ru|быть||1ç|fut|ind|tamamlanmamış}} 1lq60grdizqqrcwl6pbuqign5ggpdfk будете 0 1591052 5672601 2026-06-29T21:37:27Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дете}} # {{çekim|dil=ru|быть||2ç|fut|ind|tamamlanmamış}} 5672601 wikitext text/x-wiki ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дете}} # {{çekim|dil=ru|быть||2ç|fut|ind|tamamlanmamış}} 01kdk7eji69ahh4tte4juic27oxu0kv будут 0 1591053 5672602 2026-06-29T21:38:11Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дут}} # {{çekim|dil=ru|быть||3ç|fut|ind|tamamlanmamış}} 5672602 wikitext text/x-wiki ==Rusça== ===Eylem=== {{başlık başı|ru|çekimli eylem|baş=бу́дут}} # {{çekim|dil=ru|быть||3ç|fut|ind|tamamlanmamış}} sjol79wetewma24hux9etvseie8y4js мыслить 0 1591054 5672603 2026-06-29T21:43:30Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|мы́слить|impf}} # [[düşünmek]] 5672603 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|мы́слить|impf}} # [[düşünmek]] glkt52rzwpztu07w91fsw07kojfa2mm существовать 0 1591055 5672604 2026-06-29T21:45:37Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== ===Eylem=== {{ru-eylem|существова́ть|impf|pf=просуществова́ть}} # [[var olmak]] 5672604 wikitext text/x-wiki ==Rusça== ===Eylem=== {{ru-eylem|существова́ть|impf|pf=просуществова́ть}} # [[var olmak]] bgh5f1mvitaasink5sxvbe90czc9lmw ekzisti 0 1591056 5672605 2026-06-29T21:50:37Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Eylem=== {{eo-eylem}} # {{t|dil=eo|geçişsiz}} [[var olmak]] ====Çekimleme==== {{eo-eylem-tablo|geçişsiz=1}} ===Ek okumalar=== * {{R:eo:PIV 2020}} 5672605 wikitext text/x-wiki ==Esperanto dili== ===Eylem=== {{eo-eylem}} # {{t|dil=eo|geçişsiz}} [[var olmak]] ====Çekimleme==== {{eo-eylem-tablo|geçişsiz=1}} ===Ek okumalar=== * {{R:eo:PIV 2020}} jktci6ed19l7bzpxbgvs200zkbiowe4 ekzistinta 0 1591057 5672606 2026-06-29T21:52:02Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{eo-ortaç}} # {{eo-çekim|ekzist|anta}} 5672606 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{eo-ortaç}} # {{eo-çekim|ekzist|anta}} 737bjhdtw6ubglbbqvef8xjom3vl5cx 5672607 5672606 2026-06-29T21:52:52Z MustafaCavlak 59368 5672607 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{eo-ortaç}} # {{eo-çekim|ekzist|inta}} skqy8q33172fkxq7cds28t5d45u0i8d ekzistanta 0 1591058 5672608 2026-06-29T21:53:04Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{eo-ortaç}} # {{eo-çekim|ekzist|anta}} 5672608 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{eo-ortaç}} # {{eo-çekim|ekzist|anta}} 737bjhdtw6ubglbbqvef8xjom3vl5cx ekzistonta 0 1591059 5672609 2026-06-29T21:53:20Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{eo-ortaç}} # {{eo-çekim|ekzist|onta}} 5672609 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{eo-ortaç}} # {{eo-çekim|ekzist|onta}} 7ef4m3ba2kpwpctw3zzuxmk1vh0lyx5 ekzistinto 0 1591060 5672610 2026-06-29T21:53:54Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Mastar=== {{eo-mastar}} # {{eo-çekim|ekzist|into}} 5672610 wikitext text/x-wiki ==Esperanto dili== ===Mastar=== {{eo-mastar}} # {{eo-çekim|ekzist|into}} 5roq9f8sfrk6a8ta1xbgmel66xk41xl ekzistanto 0 1591061 5672611 2026-06-29T21:54:12Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Mastar=== {{eo-mastar}} # {{eo-çekim|ekzist|anto}} 5672611 wikitext text/x-wiki ==Esperanto dili== ===Mastar=== {{eo-mastar}} # {{eo-çekim|ekzist|anto}} habef4qhpj9oh8uvogzu6ra4z3k5ln3 ekzistonto 0 1591062 5672612 2026-06-29T21:54:30Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Mastar=== {{eo-mastar}} # {{eo-çekim|ekzist|onto}} 5672612 wikitext text/x-wiki ==Esperanto dili== ===Mastar=== {{eo-mastar}} # {{eo-çekim|ekzist|onto}} 8qk64vh6s8gmwbz1sxh18n1aa7zqoad ekzistinte 0 1591063 5672613 2026-06-29T21:55:08Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ulaç=== {{başlık başı|eo|ulaç}} # {{eo-çekim|ekzist|inte}} 5672613 wikitext text/x-wiki ==Esperanto dili== ===Ulaç=== {{başlık başı|eo|ulaç}} # {{eo-çekim|ekzist|inte}} 8p8u1oztgi8x71iog1gm1s4jv0xi547 ekzistante 0 1591064 5672614 2026-06-29T21:55:25Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ulaç=== {{başlık başı|eo|ulaç}} # {{eo-çekim|ekzist|ante}} 5672614 wikitext text/x-wiki ==Esperanto dili== ===Ulaç=== {{başlık başı|eo|ulaç}} # {{eo-çekim|ekzist|ante}} pl055fqrjo64zgl4gvu3w6jm101n7bn ekzistonte 0 1591065 5672615 2026-06-29T21:55:43Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ulaç=== {{başlık başı|eo|ulaç}} # {{eo-çekim|ekzist|onte}} 5672615 wikitext text/x-wiki ==Esperanto dili== ===Ulaç=== {{başlık başı|eo|ulaç}} # {{eo-çekim|ekzist|onte}} sjikae1nw9xwl1gutcfo7hb6l3kbr0h ekzistintan 0 1591066 5672616 2026-06-29T21:56:54Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|intan}} 5672616 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|intan}} qzeqwoy2if4zco54e5rrckhmyhg3mix ekzistintaj 0 1591067 5672617 2026-06-29T21:57:20Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|intaj}} 5672617 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|intaj}} m9hhag9uhey23lxyq6x98kn700xwg8p ekzistintajn 0 1591068 5672618 2026-06-29T21:57:42Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|intajn}} 5672618 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|intajn}} tk64czzmxjsuczdxm1irsogihqvkf11 ekzistantan 0 1591069 5672619 2026-06-29T21:58:01Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|antan}} 5672619 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|antan}} sukqh7d7bh90lzyqx7i8d3nacpahzdx ekzistantaj 0 1591070 5672620 2026-06-29T21:58:22Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|antaj}} 5672620 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|antaj}} t11sa36ualufslq98zqj0fbjqsq781j ekzistantajn 0 1591071 5672621 2026-06-29T21:58:46Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|antajn}} 5672621 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|antajn}} b9nkry4wx086gr6omy0jymjmepqraqm ekzistontan 0 1591072 5672622 2026-06-29T21:59:18Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|ontan}} 5672622 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|ontan}} e9ry9d0rkkebjm2anda7wp1uwgx4ioy ekzistontaj 0 1591073 5672623 2026-06-29T21:59:39Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|ontaj}} 5672623 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|ontaj}} anm845ptz1s6pvzmp2s7qj9xinp4afw ekzistontajn 0 1591074 5672624 2026-06-29T22:00:00Z MustafaCavlak 59368 Yeni sayfa : ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|ontajn}} 5672624 wikitext text/x-wiki ==Esperanto dili== ===Ortaç=== {{başlık başı|eo|çekimli ortaç}} # {{eo-çekim|ekzist|ontajn}} 52xj5sfzgifx90kxktcx1w1thosjts9 λεωφόροι 0 1591075 5672632 2026-06-29T22:18:29Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||nom//voc|ç}} 5672632 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||nom//voc|ç}} f42n7sofc1brtfmwlhqn4rlxjs7bmf3 λεωφόρου 0 1591076 5672633 2026-06-29T22:18:50Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||gen|t}} 5672633 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||gen|t}} igx0dylk0vb23o59vhi16rorfxi5xkp λεωφόρων 0 1591077 5672634 2026-06-29T22:19:12Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||gen|ç}} 5672634 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||gen|ç}} 005eaus1e4jf07ezo9pfq4h7le9a2ap λεωφόρο 0 1591078 5672635 2026-06-29T22:19:24Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||acc|t}} 5672635 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||acc|t}} n87fo0huqn5z797pu0rr3chcopdni1j λεωφόρους 0 1591079 5672636 2026-06-29T22:19:40Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||acc|ç}} 5672636 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||acc|ç}} k5krn7bldn8x2xgxz5jqpy8pssvokkg λεωφόρε 0 1591080 5672637 2026-06-29T22:19:53Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||voc|t}} 5672637 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|λεωφόρος||voc|t}} 3rxc1mxvfnfk523d53zsgoamk71qzxh αερολιμένα 0 1591081 5672638 2026-06-29T22:20:45Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αερολιμένας||gen//acc//voc|t}} 5672638 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αερολιμένας||gen//acc//voc|t}} hd0y9javoctgucbpidqz17sqvbw138p αερολιμένων 0 1591082 5672640 2026-06-29T22:21:18Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αερολιμένας||gen|ç}} 5672640 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αερολιμένας||gen|ç}} 50hf3y3rkp2xq3l2gc0d3kqbfbe8b2t -τήρες 0 1591083 5672641 2026-06-29T22:22:16Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Son ek=== {{başlık başı|el|çekimli son ek}} # {{çekim|dil=el|-τήρας||nom//acc//voc|ç}} 5672641 wikitext text/x-wiki ==Yunanca== ===Son ek=== {{başlık başı|el|çekimli son ek}} # {{çekim|dil=el|-τήρας||nom//acc//voc|ç}} fanfs5pu3he07uax11oh48mo1lb1chd σωλήνες 0 1591084 5672642 2026-06-29T22:24:40Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|σωλήνας||nom//acc//voc|ç}} 5672642 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|σωλήνας||nom//acc//voc|ç}} hqnppu8scpvy8389w53tjo3g45suzjq σωλήνα 0 1591085 5672643 2026-06-29T22:25:07Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|σωλήνας||gen//acc//voc|t}} 5672643 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|σωλήνας||gen//acc//voc|t}} 9lle8v11b1m66ermqif4guus2b973r4 σωλήνων 0 1591086 5672644 2026-06-29T22:25:21Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|σωλήνας||gen|ç}} 5672644 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|σωλήνας||gen|ç}} 0wmblw4iztuk9cah072b54paz3uymru αδαμαντοπωλεία 0 1591087 5672646 2026-06-29T22:30:17Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αδαμαντοπωλείο||nom//acc//voc|ç}} 5672646 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αδαμαντοπωλείο||nom//acc//voc|ç}} 4izzyyaenivpqh18u9hliwc1fu5i4sr αδαμαντοπωλείου 0 1591088 5672647 2026-06-29T22:30:35Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αδαμαντοπωλείο||gen|t}} 5672647 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αδαμαντοπωλείο||gen|t}} 00soa78okb2fnublt53aggpmpmb4mnc αδαμαντοπωλείων 0 1591089 5672648 2026-06-29T22:30:51Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αδαμαντοπωλείο||gen|ç}} 5672648 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|αδαμαντοπωλείο||gen|ç}} r2thwfc0dlruabuxl7xio8v8i0m78av ψυχιατρεία 0 1591090 5672649 2026-06-29T22:32:12Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ψυχιατρείο||nom//acc//voc|ç}} 5672649 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ψυχιατρείο||nom//acc//voc|ç}} 14j4yt3y1o49b7zfgo82m8vmn54cwis ψυχιατρείου 0 1591091 5672650 2026-06-29T22:32:32Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ψυχιατρείο||gen|t}} 5672650 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ψυχιατρείο||gen|t}} d62en9y3eaw9wm7a1pvf72kpgu3573l ψυχιατρείων 0 1591092 5672651 2026-06-29T22:32:49Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ψυχιατρείο||gen|ç}} 5672651 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ψυχιατρείο||gen|ç}} 275d62neqan4gka94euh6m7n5syp2nn χόρτου 0 1591093 5672652 2026-06-29T22:33:29Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|χόρτος||gen|t}} 5672652 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|χόρτος||gen|t}} q8k4rc75m4lwgo4rims1l9h3ffyoxn1 5672653 5672652 2026-06-29T22:33:38Z MustafaCavlak 59368 5672653 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|χόρτο||gen|t}} d42p8wnmnq1icg62a6npoixjggtdgbd χόρτων 0 1591094 5672654 2026-06-29T22:33:58Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|χόρτο||gen|ç}} 5672654 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|χόρτο||gen|ç}} 3vhsrilkvb3j4fbx0spzohcl7rxboiu φαρμακεία 0 1591095 5672655 2026-06-29T22:34:39Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|φαρμακείο||nom//acc//voc|ç}} 5672655 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|φαρμακείο||nom//acc//voc|ç}} 35ib5cuyxao2r0hls8i8yu89t6vvksv φαρμακείου 0 1591096 5672656 2026-06-29T22:34:54Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|φαρμακείο||gen|t}} 5672656 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|φαρμακείο||gen|t}} 6nmkipzrwjliltfdivqwyx0b0dypsja φαρμακείων 0 1591097 5672657 2026-06-29T22:35:08Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|φαρμακείο||gen|ç}} 5672657 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|φαρμακείο||gen|ç}} q1k6t9z2tlueo5oltpmxtbmp9caae3f στηθοσκόπια 0 1591098 5672658 2026-06-29T22:36:53Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|στηθοσκόπιο||nom//acc//voc|ç}} 5672658 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|στηθοσκόπιο||nom//acc//voc|ç}} lxde0uh53rawk7hqhqtvpsi4xpdzlcq στηθοσκόπιου 0 1591099 5672660 2026-06-29T22:37:08Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|στηθοσκόπιο||gen|t}} 5672660 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|στηθοσκόπιο||gen|t}} hssqs7f1izngnvwk2p5hrrwqhl8wpgy στηθοσκόπιων 0 1591100 5672661 2026-06-29T22:37:20Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|στηθοσκόπιο||gen|ç}} 5672661 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|στηθοσκόπιο||gen|ç}} don0dr6gvodgt61iuamqb3iri6ua6dm ρόπτρου 0 1591101 5672662 2026-06-29T22:38:14Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ρόπτρο||gen|t}} 5672662 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ρόπτρο||gen|t}} 1a8h77qncbfxw5oe19nxil790xkerpz ρόπτρων 0 1591102 5672663 2026-06-29T22:38:35Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ρόπτρο||gen|ç}} 5672663 wikitext text/x-wiki ==Yunanca== ===Ad=== {{başlık başı|el|çekimli ad}} # {{çekim|dil=el|ρόπτρο||gen|ç}} cfi0mw9q33xckhjy363h23p2nxbw64x фара 0 1591103 5672664 2026-06-29T23:23:24Z MustafaCavlak 59368 Yeni sayfa : ==Rusça== {{vikipedi|dil=ru}} [[Dosya:Car detail 1.jpg|küçükresim|'''фара''']] ===Köken=== {{nakledilen|ru|fr|phare}}, {{kökenli|ru|la|pharus}}, {{kökenli|ru|grc|Φάρος}}. ===Söyleniş=== * {{IPA|dil=ru|[ˈfarə]}} * {{ses|dil=ru|Ru-фара.ogg}} ===Ad=== {{başlık başı|ru|ad|baş=фа́ра|c=d}} # [[far]] ====Çekimleme==== {{ru-ad-cansız-s-D-a|фа́ра}} ===Kaynakça=== * {{R:ru:BTS}} * {{R:ru:Zarva}} 5672664 wikitext text/x-wiki ==Rusça== {{vikipedi|dil=ru}} [[Dosya:Car detail 1.jpg|küçükresim|'''фара''']] ===Köken=== {{nakledilen|ru|fr|phare}}, {{kökenli|ru|la|pharus}}, {{kökenli|ru|grc|Φάρος}}. ===Söyleniş=== * {{IPA|dil=ru|[ˈfarə]}} * {{ses|dil=ru|Ru-фара.ogg}} ===Ad=== {{başlık başı|ru|ad|baş=фа́ра|c=d}} # [[far]] ====Çekimleme==== {{ru-ad-cansız-s-D-a|фа́ра}} ===Kaynakça=== * {{R:ru:BTS}} * {{R:ru:Zarva}} atm35n87vydgx6oa82aboud132dleag ξεκαρφώνω 0 1591104 5672665 2026-06-30T00:36:01Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[çivi]]yle sabitlenmiş bir nesneyi yerinden çıkarmak, çivisini [[sökmek]], çivilerini [[çıkarmak]] 5672665 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[çivi]]yle sabitlenmiş bir nesneyi yerinden çıkarmak, çivisini [[sökmek]], çivilerini [[çıkarmak]] 37gr1jw3j32t2kpkykggqo1eosbk0lm κάρφωμα 0 1591105 5672666 2026-06-30T00:38:20Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|n}} # [[çivileme]] # {{t|dil=el|spor}} [[smaç]] 5672666 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n}} # [[çivileme]] # {{t|dil=el|spor}} [[smaç]] n5yfxpz1nj698km7oivkf1ini6dcas1 αποκαλύπτω 0 1591106 5672667 2026-06-30T00:44:17Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[ortaya çıkarmak]], [[ortaya koymak]] 5672667 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[ortaya çıkarmak]], [[ortaya koymak]] jh556bu2r1quz0twjlmysa0lbggb9h3 κάλυψη 0 1591107 5672668 2026-06-30T00:49:01Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[örtme]], [[kaplama]] # [[kapsama]] 5672668 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[örtme]], [[kaplama]] # [[kapsama]] 6chmdut6m5ty2j91bkk19k8kyopm957 καλύπτομαι 0 1591108 5672669 2026-06-30T00:50:08Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem|tip=edilgen}} # {{çekim|dil=el|καλύπτω||pass}} 5672669 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem|tip=edilgen}} # {{çekim|dil=el|καλύπτω||pass}} psswycb4orf8hvmxpyjd2nrdfzwcsa5 χιονοκάλυψη 0 1591109 5672670 2026-06-30T00:52:15Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[kar]] [[örtü]]sü, karla kaplanma 5672670 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[kar]] [[örtü]]sü, karla kaplanma hduwu6bjkz98gcm7egd6znpclqxyptk χιονόπτωση 0 1591110 5672671 2026-06-30T00:54:06Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[kar]] [[yağış]]ı, kar düşmesi 5672671 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[kar]] [[yağış]]ı, kar düşmesi 1bt8n93vxtr9zjwzac0wseakwkf5szm αξιολόγηση 0 1591111 5672672 2026-06-30T00:56:28Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[değerlendirme]] 5672672 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[değerlendirme]] 6cp76smll1nvrfl27z9xfiq9g9nvv2d αξιολογώ 0 1591112 5672673 2026-06-30T00:57:53Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[değerlendirmek]] 5672673 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[değerlendirmek]] 4r5sg4dbybxf7qypzzh9se01z418z23 αποτιμώ 0 1591113 5672674 2026-06-30T01:00:00Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[değer biçmek]], [[değerlendirmek]] 5672674 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[değer biçmek]], [[değerlendirmek]] tkrdux0zev325iysy6ohgdebeuoz67e εκτιμώ 0 1591114 5672675 2026-06-30T01:01:51Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[takdir etmek]] # [[değerlendirmek]], [[tahmin etmek]], [[değer biçmek]] 5672675 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[takdir etmek]] # [[değerlendirmek]], [[tahmin etmek]], [[değer biçmek]] qyqqgm0qu2512vohjscdda7oaiyaeqp εκτίμηση 0 1591115 5672676 2026-06-30T01:03:28Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[değerlendirme]], [[tahmin]] # [[takdir]], takdir etme 5672676 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[değerlendirme]], [[tahmin]] # [[takdir]], takdir etme ewc4upwqt2g2cndmla7tak9m7o8dxcm υπολογισμός 0 1591116 5672677 2026-06-30T01:08:02Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|e}} # [[hesap]], [[hesaplama]] 5672677 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|e}} # [[hesap]], [[hesaplama]] 3vb7pznwunhgxcdkt5bkdvolf1yqt46 κομπιουτεράκι 0 1591117 5672678 2026-06-30T01:10:16Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|n}} # [[hesap makinesi]] 5672678 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n}} # [[hesap makinesi]] 8cib4965hs3jzs5oqidvzol6e6vcs0f φυλή 0 1591118 5672679 2026-06-30T01:12:26Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[ırk]] # [[kabile]] 5672679 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[ırk]] # [[kabile]] tprnlnk5d2l2s6e9ezfo7nvzew3qsdy φυλετικός 0 1591119 5672680 2026-06-30T01:14:14Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[ırksal]] # [[kabilesel]] 5672680 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[ırksal]] # [[kabilesel]] 2ibj03mbwbm72cuvgtqdxj70xxa10wj ırksal 0 1591120 5672681 2026-06-30T01:16:30Z MustafaCavlak 59368 Yeni sayfa : ==Türkçe== ===Köken=== {{ek|dil=tr|ırk|sel|alt2=-sal}} ===Ön ad=== {{tr-ön ad|d=-}} # Irk ile ilgili. #: {{eş anlamlılar|tr|ırki}} ===Ek okumalar=== * {{KYK:TDK}} 5672681 wikitext text/x-wiki ==Türkçe== ===Köken=== {{ek|dil=tr|ırk|sel|alt2=-sal}} ===Ön ad=== {{tr-ön ad|d=-}} # Irk ile ilgili. #: {{eş anlamlılar|tr|ırki}} ===Ek okumalar=== * {{KYK:TDK}} 9gozh15xjq8k6oze3y9db7m1j59edt5 ευρύς 0 1591121 5672683 2026-06-30T01:20:32Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[geniş]] 5672683 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[geniş]] lf2hvjniqkmibz2zqe5ob7wub0vsjlt ısrarcı 0 1591122 5672685 2026-06-30T01:26:05Z MustafaCavlak 59368 Yeni sayfa : ==Türkçe== ===Köken=== {{ek|dil=tr|ısrar|ci|alt2=-cı}} ===Ön ad=== {{tr-ön ad}} # Israr eden. #: {{ux|tr|'''Israrcı''' insanlar yorucu olabilir.}} 5672685 wikitext text/x-wiki ==Türkçe== ===Köken=== {{ek|dil=tr|ısrar|ci|alt2=-cı}} ===Ön ad=== {{tr-ön ad}} # Israr eden. #: {{ux|tr|'''Israrcı''' insanlar yorucu olabilir.}} oe47s91dp4516lo1g438sazwqigpogq εμμένω 0 1591123 5672686 2026-06-30T01:28:02Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[ısrar etmek]] 5672686 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[ısrar etmek]] 9ledvge2qdchcr3a0bnl3suzszqq1rg τηλεχειριστήριο 0 1591124 5672687 2026-06-30T01:30:36Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|n}} # [[kumanda]] 5672687 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n}} # [[kumanda]] jofca4wo0rv3dct2mju5eccrgto1bff τηλεκοντρόλ 0 1591125 5672688 2026-06-30T01:31:24Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|n|inv}} # [[kumanda]] 5672688 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n|inv}} # [[kumanda]] e161o7m7xpb8z17s9qpm1nunas4t53m αυτοφωτογράφιση 0 1591126 5672689 2026-06-30T01:32:49Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[özçekim]] 5672689 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[özçekim]] m1z9jlb0ko6r9ze86ly5y89yhlgwn3n αυτοφωτογραφία 0 1591127 5672690 2026-06-30T01:34:16Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[özçekim]] 5672690 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[özçekim]] m1z9jlb0ko6r9ze86ly5y89yhlgwn3n αυτοφωτογραφίζομαι 0 1591128 5672691 2026-06-30T01:35:12Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[özçekim yapmak]] 5672691 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[özçekim yapmak]] huxy99vvqetl6pt1u93f6lfrhyj9a80 αυτοπροσωπογραφία 0 1591129 5672692 2026-06-30T01:37:01Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[otoportre]] 5672692 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[otoportre]] eyttp5il8lscgh11pfgzvgdplwh1547 προσωπογραφία 0 1591130 5672693 2026-06-30T01:39:44Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[portre]] 5672693 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[portre]] 59b7fvok9g755lhl7nwhjsf85w7l90h συνάρτηση 0 1591131 5672694 2026-06-30T01:41:51Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[fonksiyon]] 5672694 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[fonksiyon]] qcvyf8fda8bjfnlrzbhos3ygpw98gpd ορολογία 0 1591132 5672695 2026-06-30T01:43:27Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[terminoloji]] 5672695 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[terminoloji]] s84glykf7blu560qjcfvob78no58a30 μελάνι 0 1591133 5672696 2026-06-30T01:46:20Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|n}} # [[mürekkep]] 5672696 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n}} # [[mürekkep]] dw84du08z1q7yqlzyxqnlj451e2q083 μελανοδοχείο 0 1591134 5672697 2026-06-30T01:47:26Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|n}} # [[mürekkeplik]], [[hokka]] 5672697 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n}} # [[mürekkeplik]], [[hokka]] p8cr3vtpab6d07et1y01hcxewlqahy8 μελανώνω 0 1591135 5672698 2026-06-30T01:48:52Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[mürekkeplemek]] 5672698 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[mürekkeplemek]] lgsetag21mmq2k8ws3fnns2i94v0ed9 μαλάκιο 0 1591136 5672699 2026-06-30T01:50:30Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|n}} # [[yumuşakça]] 5672699 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n}} # [[yumuşakça]] 4udici004fziy5ahbxvs90efh7r4fao ομοταξία 0 1591137 5672700 2026-06-30T01:52:18Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # {{t|dil=el|taksonomi}} [[sınıf]] 5672700 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # {{t|dil=el|taksonomi}} [[sınıf]] ln8yb2n0nstugjqp8qqpl7abuhm8hk8 εγχώριος 0 1591138 5672701 2026-06-30T01:56:14Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[yerli]], [[yerel]], [[yurt içi]] 5672701 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[yerli]], [[yerel]], [[yurt içi]] 7r2nm8wtx9gpi1lvhtn4dyo41vz9m1q οικιακός 0 1591139 5672702 2026-06-30T01:59:12Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[ev]]le ilgili, [[evsel]] 5672702 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[ev]]le ilgili, [[evsel]] d4cypq6shbq1aewrpnaye2g8t9qqxau ενδοοικογενειακός 0 1591140 5672703 2026-06-30T02:01:45Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[aile]] [[iç]]i #: {{ux|el|'''ενδοοικογενειακή''' βία|aile içi şiddet}} 5672703 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[aile]] [[iç]]i #: {{ux|el|'''ενδοοικογενειακή''' βία|aile içi şiddet}} 1gc2bf0sgxiie00ex5621j95g13sev6 θερμικός 0 1591141 5672704 2026-06-30T02:06:43Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[ısıl]], [[termik]] 5672704 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad}} # [[ısıl]], [[termik]] b07je1a1o0rk7m0i668s66musd5lwh4 θόλος 0 1591142 5672705 2026-06-30T02:08:50Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|e}} # [[kubbe]] 5672705 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|e}} # [[kubbe]] kxh8h1hqqumpxlk4shnrmbua0vcu7i6 πλήττω 0 1591143 5672706 2026-06-30T02:12:02Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[sıkılmak]] ===Eylem=== {{el-eylem}} # [[vurmak]], [[darbe indirmek]] 5672706 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[sıkılmak]] ===Eylem=== {{el-eylem}} # [[vurmak]], [[darbe indirmek]] kxairhwn9w9hwuz6vo8p8bgwkfl62v6 καύσωνας 0 1591144 5672707 2026-06-30T02:15:15Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|e}} # [[sıcak]] [[hava]] [[dalga]]sı, [[yakıcı]] sıcak 5672707 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|e}} # [[sıcak]] [[hava]] [[dalga]]sı, [[yakıcı]] sıcak 8wu3cz50j4kk5v1rj8qarn83xd30a5b αντιμετωπίζω 0 1591145 5672708 2026-06-30T02:19:21Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[yüzleşmek]] # [[başa çıkmak]], üstesinden gelmeye çalışmak # [[muamele etmek]] 5672708 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[yüzleşmek]] # [[başa çıkmak]], üstesinden gelmeye çalışmak # [[muamele etmek]] 3vc4l4pn3u7g6v6914n0dsnauqmedyx ολιγαρχία 0 1591146 5672709 2026-06-30T02:20:41Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[oligarşi]] 5672709 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[oligarşi]] q90dwq7mi9m9nkhpf4107zc4vetetiv ολιγάρχης 0 1591147 5672710 2026-06-30T02:21:49Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|e}} # [[oligark]] 5672710 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|e}} # [[oligark]] qkecl6h27p3wly9lca03jtkyf2odw3g çizgi film 0 1591148 5672718 2026-06-30T06:24:19Z Satirdan kahraman 37401 Yeni sayfa : ==Türkçe== ===Köken=== *{{birleşik|dil=tr|çizgi|film}} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||çiz|gi|film}} ===Ad=== {{tr-ad}} [[File:Race Riot (1929 Cartoon).webm|küçükresim|Bir çizgi film örneği.]] #{{t|dil=tr|sinema}} Bir konuyla ilgili olarak karakterlerinin hareketlerini belirtecek biçimde art arda çizilmiş resimlerden oluşan sinema filmi. #* "Çizgi film izlemeyi çok seviyordu. Bıraksalar saatlerce, bıkmadan, çizgi film izleyebilirdi." - A... 5672718 wikitext text/x-wiki ==Türkçe== ===Köken=== *{{birleşik|dil=tr|çizgi|film}} ===Söyleniş=== *{{tr-IPA}} * {{h|dil=tr||çiz|gi|film}} ===Ad=== {{tr-ad}} [[File:Race Riot (1929 Cartoon).webm|küçükresim|Bir çizgi film örneği.]] #{{t|dil=tr|sinema}} Bir konuyla ilgili olarak karakterlerinin hareketlerini belirtecek biçimde art arda çizilmiş resimlerden oluşan sinema filmi. #* "Çizgi film izlemeyi çok seviyordu. Bıraksalar saatlerce, bıkmadan, çizgi film izleyebilirdi." - Ali Çankırılı ====Çekimleme==== {{tr-ad-tablo}} ===Kaynakça=== * {{KYK:TDK}} ===Ek okumalar=== *{{proje bağlantısı|Vikipedi}} ggv2006zi28i4m8x64cl8b13p6fiifz Epiphyllum oxypetalum 0 1591149 5672723 2026-06-30T07:27:38Z Turgut46 26665 /* */ 5672723 wikitext text/x-wiki == Dillerarası == ===Köken=== {{kökenli|mul|grc|ἐπιφύλλον ὀξυπέταλον}} alıntıdır. ===Özel ad=== {{başlık başı|mul|özel ad}} [[Dosya:Día de apertura.jpg|Epiphyllum oxypetalum|küçükresim|250px]] # {{t|kaktüsgiller|dil=mul}} ''[[Cactaceae]]'' (kaktüsgiller) familyasına ait, [[diken]] taşımayan epifitik veya litofitik bir [[sukulent]] [[kaktüs]] türü olup, [[Meksika]]'dan Orta Amerika'ya kadar uzanan tropikal ormanlarda doğal olarak yetişen, yassı ve yaprak benzeri gövdeleri sayesinde ağaç dallarında veya kayalarda tutunan ve beyaz çiçekleri sadece geceleri açan bir [[bitki]] türü. 5ny2f4rpfs06dnhwit3is2cgnem11u7 τσιγκούνης 0 1591150 5672726 2026-06-30T07:54:18Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ön ad=== {{el-ön ad|d=τσιγκούνα|n=τσιγκούνικο}} # [[cimri]] ====Çekimleme==== {{el-çekim-öa|çekim=ης-α-ικο|kök=τσιγκούν}} 5672726 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad|d=τσιγκούνα|n=τσιγκούνικο}} # [[cimri]] ====Çekimleme==== {{el-çekim-öa|çekim=ης-α-ικο|kök=τσιγκούν}} h2sk8rym8baiynzn0vrk9h9vmevujda τσιγγούνης 0 1591151 5672727 2026-06-30T07:56:22Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ön ad=== {{el-ön ad|d=τσιγγούνα|n=τσιγγούνικο}} # {{farklı|dil=el|τσιγκούνης}} ====Çekimleme==== {{el-çekim-öa|çekim=ης-α-ικο|kök=τσιγγούν}} 5672727 wikitext text/x-wiki ==Yunanca== ===Ön ad=== {{el-ön ad|d=τσιγγούνα|n=τσιγγούνικο}} # {{farklı|dil=el|τσιγκούνης}} ====Çekimleme==== {{el-çekim-öa|çekim=ης-α-ικο|kök=τσιγγούν}} o93mfkjb5rfm72xpzoar55xkdoztjl5 à nouveau 0 1591152 5672734 2026-06-30T08:40:27Z MustafaCavlak 59368 Yeni sayfa : ==Fransızca== ===Söyleniş=== * {{fr-IPA}} ===Belirteç=== {{başlık başı|fr|belirteç}} # [[yeniden]] 5672734 wikitext text/x-wiki ==Fransızca== ===Söyleniş=== * {{fr-IPA}} ===Belirteç=== {{başlık başı|fr|belirteç}} # [[yeniden]] q8iapj9l1p7u0f2yxs20ms4qnuux3h2 de nouveau 0 1591153 5672735 2026-06-30T08:42:08Z MustafaCavlak 59368 Yeni sayfa : ==Fransızca== ===Söyleniş=== * {{fr-IPA}} ===Belirteç=== {{başlık başı|fr|belirteç}} # [[tekrar]], [[bir daha]] 5672735 wikitext text/x-wiki ==Fransızca== ===Söyleniş=== * {{fr-IPA}} ===Belirteç=== {{başlık başı|fr|belirteç}} # [[tekrar]], [[bir daha]] febomxg750uo7vy14xeizazgfosv7xr αναμένω 0 1591154 5672764 2026-06-30T09:38:46Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Eylem=== {{el-eylem}} # [[beklemek]], [[öngörmek]] 5672764 wikitext text/x-wiki ==Yunanca== ===Eylem=== {{el-eylem}} # [[beklemek]], [[öngörmek]] oucrdp8fzngqiyhsowwangoorrpk14l αφήγημα 0 1591155 5672765 2026-06-30T09:40:22Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|n}} # [[anlatı]] 5672765 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|n}} # [[anlatı]] k4mztndhrli95k860xykv2m6y9btpef αφήγηση 0 1591156 5672766 2026-06-30T09:41:12Z MustafaCavlak 59368 Yeni sayfa : ==Yunanca== ===Ad=== {{el-ad|d}} # [[anlatma]], [[anlatım]] 5672766 wikitext text/x-wiki ==Yunanca== ===Ad=== {{el-ad|d}} # [[anlatma]], [[anlatım]] 8f8alh45gjfas1fqdw6hyryetao7ixd