<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Aplhg-translit</id>
	<title>Module:plhg-translit - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Aplhg-translit"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:plhg-translit&amp;action=history"/>
	<updated>2026-06-11T04:58:14Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:plhg-translit&amp;diff=528939&amp;oldid=prev</id>
		<title>Melinoë: Created page with &quot;local export = {}  --[=[  FIXME:  1. (DONE) If you write &#039;&#039;&#039;Б&#039;&#039;&#039;ез, it transliterates to &#039;&#039;&#039;B&#039;&#039;&#039;jez instead of    &#039;&#039;&#039;B&#039;&#039;&#039;ez, as it should.    -- NOTE: This currently doesn&#039;t work due to an issue in Module:languages    -- which means this module won&#039;t see style apostrophes. 2. (DONE) Convert ъ to nothing before comma or other non-letter particle, e.g.    in Однимъ словомъ, идешь на чтеніе. 3. (DONE) Make special-casing for adjectives in -...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:plhg-translit&amp;diff=528939&amp;oldid=prev"/>
		<updated>2026-06-10T14:05:42Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local export = {}  --[=[  FIXME:  1. (DONE) If you write &amp;#039;&amp;#039;&amp;#039;Б&amp;#039;&amp;#039;&amp;#039;ез, it transliterates to &amp;#039;&amp;#039;&amp;#039;B&amp;#039;&amp;#039;&amp;#039;jez instead of    &amp;#039;&amp;#039;&amp;#039;B&amp;#039;&amp;#039;&amp;#039;ez, as it should.    -- NOTE: This currently doesn&amp;#039;t work due to an issue in &lt;a href=&quot;/wiki/Module:languages&quot; title=&quot;Module:languages&quot;&gt;Module:languages&lt;/a&gt;    -- which means this module won&amp;#039;t see style apostrophes. 2. (DONE) Convert ъ to nothing before comma or other non-letter particle, e.g.    in Однимъ словомъ, идешь на чтеніе. 3. (DONE) Make special-casing for adjectives in -...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local export = {}&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
&lt;br /&gt;
FIXME:&lt;br /&gt;
&lt;br /&gt;
1. (DONE) If you write &amp;#039;&amp;#039;&amp;#039;Б&amp;#039;&amp;#039;&amp;#039;ез, it transliterates to &amp;#039;&amp;#039;&amp;#039;B&amp;#039;&amp;#039;&amp;#039;jez instead of&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;B&amp;#039;&amp;#039;&amp;#039;ez, as it should.&lt;br /&gt;
   -- NOTE: This currently doesn&amp;#039;t work due to an issue in [[Module:languages]]&lt;br /&gt;
   -- which means this module won&amp;#039;t see style apostrophes.&lt;br /&gt;
2. (DONE) Convert ъ to nothing before comma or other non-letter particle, e.g.&lt;br /&gt;
   in Однимъ словомъ, идешь на чтеніе.&lt;br /&gt;
3. (DONE) Make special-casing for adjectives in -го and for что (and friends)&lt;br /&gt;
    be the default, and implement transformations in Cyrillic rather than after&lt;br /&gt;
    translit so that we can display the transformed Cyrillic in the&lt;br /&gt;
    &amp;quot;phonetic respelling&amp;quot; notation of {{ru-IPA}}.&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local m_str_utils = require(&amp;quot;Module:string utilities&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local decompose = require(&amp;quot;Module:ru-common&amp;quot;).decompose&lt;br /&gt;
local explode = m_str_utils.explode_utf8&lt;br /&gt;
local concat = table.concat&lt;br /&gt;
local insert = table.insert&lt;br /&gt;
local ipairs = ipairs&lt;br /&gt;
local remove = table.remove&lt;br /&gt;
local rfind = m_str_utils.find&lt;br /&gt;
local rsub = m_str_utils.gsub&lt;br /&gt;
local rsplit = m_str_utils.split&lt;br /&gt;
local select = select&lt;br /&gt;
local toNFC = mw.ustring.toNFC&lt;br /&gt;
local toNFD = mw.ustring.toNFD&lt;br /&gt;
local u = m_str_utils.char&lt;br /&gt;
&lt;br /&gt;
local AC = u(0x301) -- acute = ́&lt;br /&gt;
local GR = u(0x0300) -- grave = ̀&lt;br /&gt;
local BR = u(0x0306) -- breve ̆&lt;br /&gt;
local DI = u(0x0308) -- diaeresis = ̈&lt;br /&gt;
local DIACRITICS = AC .. GR .. BR .. DI ..&lt;br /&gt;
	u(0x0302) .. -- circumflex ̂&lt;br /&gt;
	u(0x0304) .. -- macron ̄&lt;br /&gt;
	u(0x0307) .. -- dot above ̇&lt;br /&gt;
	u(0x030A) .. -- ring above ̊&lt;br /&gt;
	u(0x030C) .. -- caron ̌&lt;br /&gt;
	u(0x030F) .. -- double grave ̏&lt;br /&gt;
	u(0x0323) .. -- dot below ̣&lt;br /&gt;
	u(0x0328)    -- ogonek ̨&lt;br /&gt;
local TEMP_G = u(0xFFF1) -- substitute to prevent g from changing to v&lt;br /&gt;
local word_chars = &amp;quot;%a’%(%)%[%]&amp;quot; .. DIACRITICS&lt;br /&gt;
&lt;br /&gt;
local function ine(x) -- if not empty&lt;br /&gt;
	return x ~= &amp;quot;&amp;quot; and x or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Main letter conversion table.&lt;br /&gt;
local letters = {&lt;br /&gt;
	[&amp;quot;а&amp;quot;] = &amp;quot;a&amp;quot;, [&amp;quot;б&amp;quot;] = &amp;quot;b&amp;quot;, [&amp;quot;в&amp;quot;] = &amp;quot;v&amp;quot;, [&amp;quot;г&amp;quot;] = &amp;quot;g&amp;quot;, [&amp;quot;д&amp;quot;] = &amp;quot;d&amp;quot;, [&amp;quot;е&amp;quot;] = &amp;quot;je&amp;quot;, [&amp;quot;ж&amp;quot;] = &amp;quot;ž&amp;quot;, [&amp;quot;з&amp;quot;] = &amp;quot;z&amp;quot;, [&amp;quot;и&amp;quot;] = &amp;quot;i&amp;quot;, [&amp;quot;й&amp;quot;] = &amp;quot;j&amp;quot;, [&amp;quot;к&amp;quot;] = &amp;quot;k&amp;quot;, [&amp;quot;л&amp;quot;] = &amp;quot;l&amp;quot;, [&amp;quot;м&amp;quot;] = &amp;quot;m&amp;quot;, [&amp;quot;н&amp;quot;] = &amp;quot;n&amp;quot;, [&amp;quot;о&amp;quot;] = &amp;quot;o&amp;quot;, [&amp;quot;п&amp;quot;] = &amp;quot;p&amp;quot;, [&amp;quot;р&amp;quot;] = &amp;quot;r&amp;quot;, [&amp;quot;с&amp;quot;] = &amp;quot;s&amp;quot;, [&amp;quot;т&amp;quot;] = &amp;quot;t&amp;quot;, [&amp;quot;у&amp;quot;] = &amp;quot;u&amp;quot;, [&amp;quot;ф&amp;quot;] = &amp;quot;f&amp;quot;, [&amp;quot;х&amp;quot;] = &amp;quot;x&amp;quot;, [&amp;quot;ц&amp;quot;] = &amp;quot;c&amp;quot;, [&amp;quot;ч&amp;quot;] = &amp;quot;č&amp;quot;, [&amp;quot;ш&amp;quot;] = &amp;quot;š&amp;quot;, [&amp;quot;щ&amp;quot;] = &amp;quot;šč&amp;quot;, [&amp;quot;ъ&amp;quot;] = &amp;quot;ʺ&amp;quot;, [&amp;quot;ы&amp;quot;] = &amp;quot;y&amp;quot;, [&amp;quot;ь&amp;quot;] = &amp;quot;ʹ&amp;quot;, [&amp;quot;э&amp;quot;] = &amp;quot;e&amp;quot;, [&amp;quot;ю&amp;quot;] = &amp;quot;ju&amp;quot;, [&amp;quot;я&amp;quot;] = &amp;quot;ja&amp;quot;,&lt;br /&gt;
	[&amp;quot;А&amp;quot;] = &amp;quot;A&amp;quot;, [&amp;quot;Б&amp;quot;] = &amp;quot;B&amp;quot;, [&amp;quot;В&amp;quot;] = &amp;quot;V&amp;quot;, [&amp;quot;Г&amp;quot;] = &amp;quot;G&amp;quot;, [&amp;quot;Д&amp;quot;] = &amp;quot;D&amp;quot;, [&amp;quot;Е&amp;quot;] = &amp;quot;Je&amp;quot;, [&amp;quot;Ж&amp;quot;] = &amp;quot;Ž&amp;quot;, [&amp;quot;З&amp;quot;] = &amp;quot;Z&amp;quot;, [&amp;quot;И&amp;quot;] = &amp;quot;I&amp;quot;, [&amp;quot;Й&amp;quot;] = &amp;quot;J&amp;quot;, [&amp;quot;К&amp;quot;] = &amp;quot;K&amp;quot;, [&amp;quot;Л&amp;quot;] = &amp;quot;L&amp;quot;, [&amp;quot;М&amp;quot;] = &amp;quot;M&amp;quot;, [&amp;quot;Н&amp;quot;] = &amp;quot;N&amp;quot;, [&amp;quot;О&amp;quot;] = &amp;quot;O&amp;quot;, [&amp;quot;П&amp;quot;] = &amp;quot;P&amp;quot;, [&amp;quot;Р&amp;quot;] = &amp;quot;R&amp;quot;, [&amp;quot;С&amp;quot;] = &amp;quot;S&amp;quot;, [&amp;quot;Т&amp;quot;] = &amp;quot;T&amp;quot;, [&amp;quot;У&amp;quot;] = &amp;quot;U&amp;quot;, [&amp;quot;Ф&amp;quot;] = &amp;quot;F&amp;quot;, [&amp;quot;Х&amp;quot;] = &amp;quot;X&amp;quot;, [&amp;quot;Ц&amp;quot;] = &amp;quot;C&amp;quot;, [&amp;quot;Ч&amp;quot;] = &amp;quot;Č&amp;quot;, [&amp;quot;Ш&amp;quot;] = &amp;quot;Š&amp;quot;, [&amp;quot;Щ&amp;quot;] = &amp;quot;Šč&amp;quot;, [&amp;quot;Ъ&amp;quot;] = &amp;quot;ʺ&amp;quot;, [&amp;quot;Ы&amp;quot;] = &amp;quot;Y&amp;quot;, [&amp;quot;Ь&amp;quot;] = &amp;quot;ʹ&amp;quot;, [&amp;quot;Э&amp;quot;] = &amp;quot;E&amp;quot;, [&amp;quot;Ю&amp;quot;] = &amp;quot;Ju&amp;quot;, [&amp;quot;Я&amp;quot;] = &amp;quot;Ja&amp;quot;,&lt;br /&gt;
	-- Russian style quotes&lt;br /&gt;
	[&amp;quot;«&amp;quot;] = &amp;quot;“&amp;quot;, [&amp;quot;»&amp;quot;] = &amp;quot;”&amp;quot;,&lt;br /&gt;
	-- archaic, pre-1918 letters&lt;br /&gt;
	[&amp;quot;і&amp;quot;] = &amp;quot;i&amp;quot;, [&amp;quot;ѳ&amp;quot;] = &amp;quot;f&amp;quot;, [&amp;quot;ѣ&amp;quot;] = &amp;quot;jě&amp;quot;, [&amp;quot;ѵ&amp;quot;] = &amp;quot;i&amp;quot;,&lt;br /&gt;
	[&amp;quot;І&amp;quot;] = &amp;quot;I&amp;quot;, [&amp;quot;Ѳ&amp;quot;] = &amp;quot;F&amp;quot;, [&amp;quot;Ѣ&amp;quot;] = &amp;quot;Jě&amp;quot;, [&amp;quot;Ѵ&amp;quot;] = &amp;quot;I&amp;quot;,&lt;br /&gt;
	-- archaic, pre-1708 letters (most of these are covered by aliases below)&lt;br /&gt;
	[&amp;quot;ѥ&amp;quot;] = &amp;quot;je&amp;quot;, [&amp;quot;ѯ&amp;quot;] = &amp;quot;ks&amp;quot;, [&amp;quot;ѱ&amp;quot;] = &amp;quot;ps&amp;quot;,&lt;br /&gt;
	[&amp;quot;Ѥ&amp;quot;] = &amp;quot;Je&amp;quot;, [&amp;quot;Ѯ&amp;quot;] = &amp;quot;Ks&amp;quot;, [&amp;quot;Ѱ&amp;quot;] = &amp;quot;Ps&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Treat most archaic letters as aliases. Exceptions:&lt;br /&gt;
-- ѥ is not the same as е, because it doesn&amp;#039;t lose iotation after a consonant.&lt;br /&gt;
-- ѯ and ѱ can&amp;#039;t be treated as aliases, because mapping 1 character to 2 messes&lt;br /&gt;
-- can cause the logic which checks the capitalization of adjacent letters to&lt;br /&gt;
-- become unreliable. This only affects the uppercase forms, but the lowercase&lt;br /&gt;
-- forms are also excepted for consistency.&lt;br /&gt;
local aliases = {&lt;br /&gt;
	[&amp;quot;є&amp;quot;] = &amp;quot;е&amp;quot;, [&amp;quot;ꙁ&amp;quot;] = &amp;quot;з&amp;quot;, [&amp;quot;ꙃ&amp;quot;] = &amp;quot;з&amp;quot;, [&amp;quot;ѕ&amp;quot;] = &amp;quot;з&amp;quot;, [&amp;quot;ї&amp;quot;] = &amp;quot;і&amp;quot;, [&amp;quot;ꙋ&amp;quot;] = &amp;quot;у&amp;quot;, [&amp;quot;ѡ&amp;quot;] = &amp;quot;о&amp;quot;, [&amp;quot;ѿ&amp;quot;] = &amp;quot;о&amp;quot;, [&amp;quot;ꙑ&amp;quot;] = &amp;quot;ы&amp;quot;, [&amp;quot;ꙗ&amp;quot;] = &amp;quot;я&amp;quot;, [&amp;quot;ѧ&amp;quot;] = &amp;quot;я&amp;quot;, [&amp;quot;ѫ&amp;quot;] = &amp;quot;у&amp;quot;, [&amp;quot;ѩ&amp;quot;] = &amp;quot;я&amp;quot;, [&amp;quot;ѭ&amp;quot;] = &amp;quot;ю&amp;quot;,&lt;br /&gt;
	[&amp;quot;Є&amp;quot;] = &amp;quot;Е&amp;quot;, [&amp;quot;Ꙁ&amp;quot;] = &amp;quot;З&amp;quot;, [&amp;quot;Ꙃ&amp;quot;] = &amp;quot;З&amp;quot;, [&amp;quot;Ѕ&amp;quot;] = &amp;quot;З&amp;quot;, [&amp;quot;Ї&amp;quot;] = &amp;quot;І&amp;quot;, [&amp;quot;Ꙋ&amp;quot;] = &amp;quot;У&amp;quot;, [&amp;quot;Ѡ&amp;quot;] = &amp;quot;О&amp;quot;, [&amp;quot;Ѿ&amp;quot;] = &amp;quot;О&amp;quot;, [&amp;quot;Ꙑ&amp;quot;] = &amp;quot;Ы&amp;quot;, [&amp;quot;Ꙗ&amp;quot;] = &amp;quot;Я&amp;quot;, [&amp;quot;Ѧ&amp;quot;] = &amp;quot;Я&amp;quot;, [&amp;quot;Ѫ&amp;quot;] = &amp;quot;У&amp;quot;, [&amp;quot;Ѩ&amp;quot;] = &amp;quot;Я&amp;quot;, [&amp;quot;Ѭ&amp;quot;] = &amp;quot;Ю&amp;quot;, [&amp;quot;&amp;#039;&amp;quot;] = &amp;quot;’&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local plain_e = {&lt;br /&gt;
	[&amp;quot;е&amp;quot;] = &amp;quot;e&amp;quot;, [&amp;quot;ѣ&amp;quot;] = &amp;quot;ě&amp;quot;, [&amp;quot;э&amp;quot;] = &amp;quot;ɛ&amp;quot;,&lt;br /&gt;
	[&amp;quot;Е&amp;quot;] = &amp;quot;E&amp;quot;, [&amp;quot;Ѣ&amp;quot;] = &amp;quot;Ě&amp;quot;, [&amp;quot;Э&amp;quot;] = &amp;quot;Ɛ&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local jo_letters = {&lt;br /&gt;
	[&amp;quot;ё&amp;quot;] = &amp;quot;jo&amp;quot;, [&amp;quot;ѣ̈&amp;quot;] = &amp;quot;jǒ&amp;quot;, [&amp;quot;я̈&amp;quot;] = &amp;quot;jǫ&amp;quot;,&lt;br /&gt;
	[&amp;quot;Ё&amp;quot;] = &amp;quot;Jo&amp;quot;, [&amp;quot;Ѣ̈&amp;quot;] = &amp;quot;Jǒ&amp;quot;, [&amp;quot;Я̈&amp;quot;] = &amp;quot;Jǫ&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local vowels = &amp;quot;аеиіоуыѣэюяѥѵaæɐeəɛiɪɨoɵuyʊʉАЕИІОУЫѢЭЮЯѤѴAEƐIOUY&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- Apply transformations to the Cyrillic to more closely match pronunciation.&lt;br /&gt;
-- Return two arguments: the &amp;quot;original&amp;quot; text (after decomposing composed&lt;br /&gt;
-- grave characters), and the transformed text. If the two are different,&lt;br /&gt;
-- {{ru-IPA}} should display a &amp;quot;phonetic respelling&amp;quot; notation. &lt;br /&gt;
-- NOADJ disables special-casing for adjectives in -го, while FORCEADJ forces&lt;br /&gt;
-- special-casing for adjectives, including those in -аго (pre-reform spelling)&lt;br /&gt;
-- and disables checking for exceptions (e.g. много, ого). NOSHTO disables&lt;br /&gt;
-- special-casing for что and related words.&lt;br /&gt;
function export.apply_tr_fixes(text, noadj, noshto, forceadj)&lt;br /&gt;
	-- normalize any aliases&lt;br /&gt;
	text = text:gsub(&amp;quot;.[\128-\191]*&amp;quot;, aliases)&lt;br /&gt;
	-- decompose stress accents without decomposing letters we want to treat&lt;br /&gt;
	-- as units (e.g. й or ё)&lt;br /&gt;
	text = decompose(text)&lt;br /&gt;
&lt;br /&gt;
	local origtext = text&lt;br /&gt;
	-- the second half of the if-statement below is an optimization; see above.&lt;br /&gt;
	if not noadj and text:find(&amp;quot;го&amp;quot;) then&lt;br /&gt;
		local v = {[&amp;quot;г&amp;quot;] = &amp;quot;в&amp;quot;, [&amp;quot;Г&amp;quot;] = &amp;quot;В&amp;quot;}&lt;br /&gt;
		local repl = function(e, g, o, sja) return e .. v[g] .. o .. (sja or &amp;quot;&amp;quot;) end&lt;br /&gt;
		-- Handle какого-нибудь/-либо/-то; must be done first because of an exception&lt;br /&gt;
		-- made for бого-, снего-, etc.&lt;br /&gt;
		text = rsub(text, &amp;quot;([кКтТ][аА][кК][оеОЕ&amp;quot; .. (forceadj and &amp;quot;аА&amp;quot; or &amp;quot;&amp;quot;) .. &amp;quot;][&amp;quot; .. AC .. GR .. &amp;quot;]?)([гГ])([оО]%-)&amp;quot;, repl)&lt;br /&gt;
		if not forceadj then&lt;br /&gt;
			local function go(text, case)&lt;br /&gt;
				local pattern = rsub(case, &amp;quot;^(.)(.*)(го[&amp;quot; .. AC .. GR .. &amp;quot;]?)(%-?)$&amp;quot;, function(m1, m2, m3, m4)&lt;br /&gt;
					m1 = &amp;quot;%f[%a&amp;quot; .. AC .. GR .. &amp;quot;]([&amp;quot; .. m1:uupper() .. m1 .. &amp;quot;]&amp;quot;&lt;br /&gt;
					m2 = m2:gsub(&amp;quot;\204[\128\129]&amp;quot;, &amp;quot;[&amp;quot; .. AC .. GR .. &amp;quot;]?&amp;quot;) .. &amp;quot;)&amp;quot;&lt;br /&gt;
					m3 = m3:gsub(&amp;quot;\204[\128\129]&amp;quot;, &amp;quot;[&amp;quot; .. AC .. GR .. &amp;quot;]?&amp;quot;)&lt;br /&gt;
						:gsub(&amp;quot;^г(.*)&amp;quot;, &amp;quot;г(%1&amp;quot;)&lt;br /&gt;
					m4 = m4 == &amp;quot;-&amp;quot; and &amp;quot;%-)&amp;quot; or &amp;quot;)%f[^%a&amp;quot; .. AC .. GR .. &amp;quot;]&amp;quot;&lt;br /&gt;
					return m1 .. m2 .. m3 .. m4&lt;br /&gt;
				end)&lt;br /&gt;
				return rsub(text, pattern, &amp;quot;%1&amp;quot; .. TEMP_G .. &amp;quot;%2&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
			for _, case in ipairs{&amp;quot;мно́го&amp;quot;, &amp;quot;н[еа]мно́го&amp;quot;, &amp;quot;до́рого&amp;quot;, &amp;quot;недо́рого&amp;quot;, &amp;quot;стро́го&amp;quot;, &amp;quot;нестро́го&amp;quot;, &amp;quot;на́строго&amp;quot;, &amp;quot;убо́го&amp;quot;, &amp;quot;пол[ао]́го&amp;quot;} do&lt;br /&gt;
				text = go(text, case)&lt;br /&gt;
			end&lt;br /&gt;
			-- check for neuter short forms of compound adjectives in -но́гий&lt;br /&gt;
			if rfind(text, &amp;quot;но[&amp;quot; .. AC .. GR .. &amp;quot;]?го%f[^%a&amp;quot; .. AC .. GR .. &amp;quot;]&amp;quot;) then&lt;br /&gt;
				for _, case in ipairs{&amp;quot;безно́го&amp;quot;, &amp;quot;босоно́го&amp;quot;, &amp;quot;веслоно́го&amp;quot;, &amp;quot;длинноно́го&amp;quot;, &amp;quot;двуно́го&amp;quot;, &amp;quot;коротконо́го&amp;quot;, &amp;quot;кривоно́го&amp;quot;, &amp;quot;одноно́го&amp;quot;, &amp;quot;пятино́го&amp;quot;, &amp;quot;трёхно́го&amp;quot;, &amp;quot;трехно́го&amp;quot;, &amp;quot;хромоно́го&amp;quot;, &amp;quot;четвероно́го&amp;quot;, &amp;quot;шестино́го&amp;quot;} do&lt;br /&gt;
					text = go(text, case)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			for _, case in ipairs{&amp;quot;ого́&amp;quot;, &amp;quot;го́го&amp;quot;, &amp;quot;ваго́го&amp;quot;, &amp;quot;ло́го&amp;quot;, &amp;quot;п[ео]́го&amp;quot;, &amp;quot;со́го&amp;quot;, &amp;quot;То́го&amp;quot;, &amp;quot;ле́го&amp;quot;, &amp;quot;игого́&amp;quot;, &amp;quot;огого́&amp;quot;, &amp;quot;альбиньязего&amp;quot;, &amp;quot;д[иі]е́го&amp;quot;, &amp;quot;бо́лого&amp;quot;, &amp;quot;гр[иі]е́го&amp;quot;, &amp;quot;манче́го&amp;quot;, &amp;quot;пичис[иі]е́го&amp;quot;, &amp;quot;тенкодого&amp;quot;, &amp;quot;хио́го&amp;quot;, &amp;quot;аго-&amp;quot;, &amp;quot;его-&amp;quot;, &amp;quot;ого-&amp;quot;} do&lt;br /&gt;
				text = go(text, case)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--handle genitive/accusative endings, which are spelled -ого/-его/-аго&lt;br /&gt;
		-- (-ogo/-ego/-ago) but transliterated -ovo/-evo/-avo; only for adjectives&lt;br /&gt;
		-- and pronouns, excluding words like много, ого (-аго occurs in&lt;br /&gt;
		-- pre-reform spelling); \204\129 is an acute accent, \204\128 is a grave accent&lt;br /&gt;
		local pattern = &amp;quot;([оеОЕ&amp;quot; .. (forceadj and &amp;quot;аА&amp;quot; or &amp;quot;&amp;quot;) .. &amp;quot;][&amp;quot; .. AC .. GR .. &amp;quot;]?)([гГ])([оО][&amp;quot; .. AC .. GR .. &amp;quot;]?)&amp;quot;&lt;br /&gt;
		local reflexive = &amp;quot;([сС][яЯ][&amp;quot; .. AC .. GR .. &amp;quot;]?)&amp;quot;&lt;br /&gt;
		text = rsub(text, pattern .. &amp;quot;%f[^%a&amp;quot; .. AC .. GR .. TEMP_G .. &amp;quot;]&amp;quot;, repl)&lt;br /&gt;
		text = rsub(text, pattern .. reflexive .. &amp;quot;%f[^%a&amp;quot; .. AC .. GR .. TEMP_G .. &amp;quot;]&amp;quot;, repl)&lt;br /&gt;
		-- handle сегодня&lt;br /&gt;
		text = rsub(text, &amp;quot;%f[%a&amp;quot; .. AC .. GR .. &amp;quot;]([Сс]е)г(о[&amp;quot; .. AC .. GR .. &amp;quot;]?дня)%f[^%a&amp;quot; .. AC .. GR .. &amp;quot;]&amp;quot;, &amp;quot;%1в%2&amp;quot;)&lt;br /&gt;
		-- handle сегодняшн-&lt;br /&gt;
		text = rsub(text, &amp;quot;%f[%a&amp;quot; .. AC .. GR .. &amp;quot;]([Сс]е)г(о[&amp;quot; .. AC .. GR .. &amp;quot;]?дняшн)&amp;quot;, &amp;quot;%1в%2&amp;quot;)&lt;br /&gt;
		-- replace TEMP_G with g; must be done after the -go -&amp;gt; -vo changes&lt;br /&gt;
		text = rsub(text, TEMP_G, &amp;quot;г&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- the second half of the if-statement below is an optimization; see above.&lt;br /&gt;
	if not noshto and text:find(&amp;quot;то&amp;quot;) then&lt;br /&gt;
		local ch2sh = {[&amp;quot;ч&amp;quot;] = &amp;quot;ш&amp;quot;, [&amp;quot;Ч&amp;quot;] = &amp;quot;Ш&amp;quot;}&lt;br /&gt;
		-- Handle что&lt;br /&gt;
		text = rsub(text, &amp;quot;%f[%a&amp;quot; .. AC .. GR .. &amp;quot;]([Чч])(то[&amp;quot; .. AC .. GR .. &amp;quot;]?)%f[^%a&amp;quot; .. AC .. GR .. &amp;quot;]&amp;quot;,&lt;br /&gt;
			function(ch, to) return ch2sh[ch] .. to end)&lt;br /&gt;
		-- Handle чтобы, чтоб&lt;br /&gt;
		text = rsub(text, &amp;quot;%f[%a&amp;quot; .. AC .. GR .. &amp;quot;]([Чч])(то[&amp;quot; .. AC .. GR .. &amp;quot;]?бы?)%f[^%a&amp;quot; .. AC .. GR .. &amp;quot;]&amp;quot;,&lt;br /&gt;
			function(ch, to) return ch2sh[ch] .. to end)&lt;br /&gt;
		-- Handle ничто&lt;br /&gt;
		text = rsub(text, &amp;quot;%f[%a&amp;quot; .. AC .. GR .. &amp;quot;]([Нн]и)ч(то[&amp;quot; .. AC .. GR .. &amp;quot;]?)%f[^%a&amp;quot; .. AC .. GR .. &amp;quot;]&amp;quot;, &amp;quot;%1ш%2&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Handle мягкий, лёгкий, легчать, etc.&lt;br /&gt;
	text = rsub(text, &amp;quot;([МмЛл][яеё][&amp;quot; .. AC .. GR .. &amp;quot;]?)г([кч])&amp;quot;, &amp;quot;%1х%2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	return origtext, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
	-- If и, check if it&amp;#039;s actually й to avoid wrongly treating it as a vowel.&lt;br /&gt;
	local function handle_short_i(word, ch, i, adjust)&lt;br /&gt;
		if (ch == &amp;quot;и&amp;quot; or ch == &amp;quot;И&amp;quot;) and word[i] == BR then&lt;br /&gt;
			-- Remove the breve; only used by get_next_char.&lt;br /&gt;
			if adjust then&lt;br /&gt;
				remove(word, i)&lt;br /&gt;
			end&lt;br /&gt;
			ch = toNFC(ch .. BR)&lt;br /&gt;
			word[i - 1] = ch&lt;br /&gt;
		end&lt;br /&gt;
		return ch&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function get_prev_char(word, i)&lt;br /&gt;
		local j, ch = 0&lt;br /&gt;
		repeat&lt;br /&gt;
			j = j + 1&lt;br /&gt;
			ch = word[i - j]&lt;br /&gt;
		until not (ch and (DIACRITICS .. &amp;quot;()’&amp;quot;):find(ch, nil, true))&lt;br /&gt;
		return handle_short_i(word, ch, i - j + 1)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function get_next_char(word, i)&lt;br /&gt;
		local j, ch = 0&lt;br /&gt;
		repeat&lt;br /&gt;
			j = j + 1&lt;br /&gt;
			ch = word[i + j]&lt;br /&gt;
		until ch ~= &amp;quot;(&amp;quot; and ch ~= &amp;quot;)&amp;quot;&lt;br /&gt;
		return handle_short_i(word, ch, i + j + 1, true)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Check if a vowel should be made &amp;quot;plain&amp;quot; (usually by removing the &amp;quot;j&amp;quot;&lt;br /&gt;
	-- in the transliteration). Returns true if `prev` is in the string `check`.&lt;br /&gt;
	-- If `this` and `prev` are both uppercase, always returns false (on the&lt;br /&gt;
	-- assumption the term is an initialism).&lt;br /&gt;
	-- Note: We check both because of terms like Романо-д’Эццелино and&lt;br /&gt;
	-- Комон-л’Эванте, where an uppercase `this` follows a lowercase `prev`,&lt;br /&gt;
	-- (since the apostrophe is ignored).&lt;br /&gt;
	local function check_plain(this, prev, check, in_check)&lt;br /&gt;
		if prev and (this == this:ulower() or prev == prev:ulower()) then&lt;br /&gt;
			if check:match(prev, 1, true) then&lt;br /&gt;
				return in_check&lt;br /&gt;
			end&lt;br /&gt;
			return not in_check&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Convert any jos (ё, ѣ̈, я̈) as a special-case.&lt;br /&gt;
	local function is_jo_letter(this, prev, output, word, d)&lt;br /&gt;
		local tr = jo_letters[this]&lt;br /&gt;
		if not tr then&lt;br /&gt;
			return&lt;br /&gt;
		end&lt;br /&gt;
		-- Remove &amp;quot;j&amp;quot; if preceded by a hushing consonant (ж ч ш щ).&lt;br /&gt;
		if check_plain(this, prev, &amp;quot;жчшщЖЧШЩ&amp;quot;, true) then&lt;br /&gt;
			tr = tr:sub(2)&lt;br /&gt;
			if this == this:uupper() then&lt;br /&gt;
				tr = tr:uupper()&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		insert(output, tr)&lt;br /&gt;
		-- Note the position, so we can give it an implicit primary stress&lt;br /&gt;
		-- if necessary (unless it already has secondary stress; shouldn&amp;#039;t&lt;br /&gt;
		-- ever come after primary stress, but just in case it does we&lt;br /&gt;
		-- shouldn&amp;#039;t override it or give the jo two stress marks.&lt;br /&gt;
		if word[d.i + 1] ~= GR then&lt;br /&gt;
			d.final_jo = #output&lt;br /&gt;
		end&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function do_iteration(output, word, d)&lt;br /&gt;
		-- Get current, previous and next characters, skipping over brackets, and&lt;br /&gt;
		-- ignoring diacritics for the previous character (which simplifies checks).&lt;br /&gt;
		local this = word[d.i]&lt;br /&gt;
		local prev = get_prev_char(word, d.i)&lt;br /&gt;
		local nxt = get_next_char(word, d.i)&lt;br /&gt;
		-- A word is monosyllabic if it has only one vowel.&lt;br /&gt;
		if vowels:find(this, 1, true) then&lt;br /&gt;
			d.vowels = d.vowels + 1&lt;br /&gt;
		end&lt;br /&gt;
		if nxt == DI then&lt;br /&gt;
			d.i = d.i + 1&lt;br /&gt;
			this = toNFC(this .. DI)&lt;br /&gt;
			if is_jo_letter(this, prev, output, word, d) then&lt;br /&gt;
				return&lt;br /&gt;
			end&lt;br /&gt;
		elseif nxt == BR then&lt;br /&gt;
			d.i = d.i + 1&lt;br /&gt;
			this = toNFC(this .. BR)&lt;br /&gt;
		-- Note that explicit stress has been found, which prevents any&lt;br /&gt;
		-- implicit stress from being added for jos.&lt;br /&gt;
		elseif this == AC then&lt;br /&gt;
			d.primary = true&lt;br /&gt;
		-- After a lowercase consonant or at the start of a suffix, е becomes&lt;br /&gt;
		-- e, ѣ becomes ě and э becomes ɛ; after й, this only applies to э.&lt;br /&gt;
		elseif plain_e[this] and (&lt;br /&gt;
			check_plain(this, prev, vowels .. &amp;quot;ʹʺъЪьЬ&amp;quot; .. ((this == &amp;quot;э&amp;quot; or this == &amp;quot;Э&amp;quot;) and &amp;quot;&amp;quot; or &amp;quot;йЙ&amp;quot;), false) or&lt;br /&gt;
			not prev and d.dash_before&lt;br /&gt;
		) then&lt;br /&gt;
			insert(output, plain_e[this])&lt;br /&gt;
			return&lt;br /&gt;
		-- ю becomes u if if preceded by ж or ш.&lt;br /&gt;
		elseif (&lt;br /&gt;
			(this == &amp;quot;ю&amp;quot; or this == &amp;quot;Ю&amp;quot;) and&lt;br /&gt;
			check_plain(this, prev, &amp;quot;жшЖШ&amp;quot;, true)&lt;br /&gt;
		) then&lt;br /&gt;
			insert(output, this == &amp;quot;ю&amp;quot; and &amp;quot;u&amp;quot; or &amp;quot;U&amp;quot;)&lt;br /&gt;
			return&lt;br /&gt;
		-- Make lowercase izhitsa display as -v- after /a/, /e/ and /i/&lt;br /&gt;
		-- (matching the equivalent Greek digraphs αυ, ευ and ηυ).&lt;br /&gt;
		elseif (&lt;br /&gt;
			this == &amp;quot;ѵ&amp;quot; and&lt;br /&gt;
			prev and (&amp;quot;аеиіѣэяѥaæɐeəɛiɪɨАЕИІѢЭЯѤAEƐI&amp;quot;):find(prev, 1, true)&lt;br /&gt;
		) then&lt;br /&gt;
			this = &amp;quot;в&amp;quot;&lt;br /&gt;
			word[d.i] = &amp;quot;в&amp;quot;&lt;br /&gt;
		-- Ignore word-final hard signs.&lt;br /&gt;
		elseif (this == &amp;quot;ъ&amp;quot; or this == &amp;quot;Ъ&amp;quot;) and d.i == #word then&lt;br /&gt;
			return&lt;br /&gt;
		end&lt;br /&gt;
		insert(output, letters[this] or this)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Transliterate after the pronunciation-related transformations of&lt;br /&gt;
	-- export.apply_tr_fixes() have been applied. Called from {{ru-IPA}}.&lt;br /&gt;
	-- `jo_accent` is as in export.tr().&lt;br /&gt;
	function export.tr_after_fixes(text, jo_accent)&lt;br /&gt;
		-- normalize any aliases&lt;br /&gt;
		text = toNFC(text:gsub(&amp;quot;.[\128-\191]*&amp;quot;, aliases))&lt;br /&gt;
		local output = {}&lt;br /&gt;
		&lt;br /&gt;
		-- Note: We use ustring gsub because ustring gmatch is bugged, and&lt;br /&gt;
		-- it&amp;#039;s easy to make gsub do the same thing.&lt;br /&gt;
		rsub(text, &amp;quot;([^&amp;quot; .. word_chars .. &amp;quot;]*)([&amp;quot; .. word_chars .. &amp;quot;]*)&amp;quot;, function(before, word)&lt;br /&gt;
			for _, ch in ipairs(explode(before)) do&lt;br /&gt;
				insert(output, ch)&lt;br /&gt;
			end&lt;br /&gt;
			-- FIXME: Do this in one loop instead of splitting by word.&lt;br /&gt;
			word = explode(toNFD(word))&lt;br /&gt;
			local d = {&lt;br /&gt;
				i = 0,&lt;br /&gt;
				vowels = 0&lt;br /&gt;
			}&lt;br /&gt;
			-- Prefix if it&amp;#039;s preceded by &amp;quot;^-&amp;quot; or &amp;quot; -&amp;quot;.&lt;br /&gt;
			if output[#output] == &amp;quot;-&amp;quot; then&lt;br /&gt;
				local prev = output[#output - 1]&lt;br /&gt;
				if not prev or rfind(prev, &amp;quot;%s&amp;quot;) then&lt;br /&gt;
					d.dash_before = true&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			while d.i &amp;lt; #word do&lt;br /&gt;
				d.i = d.i + 1&lt;br /&gt;
				do_iteration(output, word, d)&lt;br /&gt;
			end&lt;br /&gt;
			-- Add an implicit primary stress to a jo (if applicable).&lt;br /&gt;
			-- Jos do not implicitly take stress accents if an explicit primary&lt;br /&gt;
			-- stress is given. Otherwise, the final jo which doesn&amp;#039;t have&lt;br /&gt;
			-- secondary stress takes primary stress.&lt;br /&gt;
			-- Prefixes do not take implicit primary stress.&lt;br /&gt;
			-- Primary stress will be shown on monosyllables if either they&lt;br /&gt;
			-- are a suffix or `jo_accent` is &amp;quot;mono&amp;quot;.&lt;br /&gt;
			if (&lt;br /&gt;
				jo_accent ~= &amp;quot;none&amp;quot; and&lt;br /&gt;
				d.final_jo and&lt;br /&gt;
				(not (d.primary or word[#word] == &amp;quot;-&amp;quot;)) and&lt;br /&gt;
				(jo_accent == &amp;quot;mono&amp;quot; or d.vowels &amp;gt; 1 or d.dash_before)&lt;br /&gt;
			) then&lt;br /&gt;
				output[d.final_jo] = output[d.final_jo] .. AC&lt;br /&gt;
			end&lt;br /&gt;
		end)&lt;br /&gt;
		&lt;br /&gt;
		return toNFC(concat(output))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Transliterates text, which should be a single word or phrase. It should&lt;br /&gt;
-- include stress marks, which are then preserved in the transliteration.&lt;br /&gt;
-- ё is a special case: it is rendered (j)ó in multisyllabic words and&lt;br /&gt;
-- monosyllabic words in multi-word phrases, but rendered (j)o without an&lt;br /&gt;
-- accent in isolated monosyllabic words. This can be overridden with the&lt;br /&gt;
-- JO_ACCENT parameter: if set to &amp;quot;mono&amp;quot;, monosyllabic words will also be&lt;br /&gt;
-- given as (j)ó (this is used in conjugation and declension tables); if set&lt;br /&gt;
-- to &amp;quot;none&amp;quot;, it will always be rendered (j)o.&lt;br /&gt;
-- NOADJ disables special-casing for adjectives in -го, while FORCEADJ forces&lt;br /&gt;
-- special-casing for adjectives and disables checking for exceptions&lt;br /&gt;
-- (e.g. много). NOSHTO disables special-casing for что and related words.&lt;br /&gt;
-- As a special case, if `lang` is a language other than &amp;quot;ru&amp;quot;, then none of&lt;br /&gt;
-- the special transformations are applied, and JO_ACCENT is set to &amp;quot;none&amp;quot;.&lt;br /&gt;
-- This is for situations which require Russian transcriptions of Cyrillic,&lt;br /&gt;
-- but where the special cases don&amp;#039;t make sense (e.g. the Cyrillization of&lt;br /&gt;
-- Mandarin, or pidgins such as Russenorsk).&lt;br /&gt;
function export.tr(text, lang, sc, jo_accent, noadj, noshto, forceadj)&lt;br /&gt;
	if (ine(lang) or &amp;quot;ru&amp;quot;) ~= &amp;quot;ru&amp;quot; then&lt;br /&gt;
		return export.tr_after_fixes(text, &amp;quot;none&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	return export.tr_after_fixes(&lt;br /&gt;
		select(2, export.apply_tr_fixes(text, noadj, noshto, forceadj)),&lt;br /&gt;
		jo_accent&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- translit with various special-case substitutions; NOADJ disables&lt;br /&gt;
-- special-casing for adjectives in -го, while FORCEADJ forces special-casing&lt;br /&gt;
-- for adjectives and disables checking for expections (e.g. много).&lt;br /&gt;
-- NOSHTO disables special-casing for что and related words. SUB is used&lt;br /&gt;
-- to implement arbitrary substitutions in the Cyrillic text before other&lt;br /&gt;
-- transformations are applied and before translit. It is of the form&lt;br /&gt;
-- FROM/TO,FROM/TO,...&lt;br /&gt;
function export.tr_sub(text, jo_accent, noadj, noshto, sub,&lt;br /&gt;
	forceadj)&lt;br /&gt;
	if type(text) == &amp;quot;table&amp;quot; then -- called directly from a template&lt;br /&gt;
		jo_accent = ine(text.args.jo_accent)&lt;br /&gt;
		noadj = ine(text.args.noadj)&lt;br /&gt;
		noshto = ine(text.args.noshto)&lt;br /&gt;
		sub = ine(text.args.sub)&lt;br /&gt;
		text = text.args[1]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if sub then&lt;br /&gt;
		local subs = rsplit(sub, &amp;quot;,&amp;quot;)&lt;br /&gt;
		for _, subpair in ipairs(subs) do&lt;br /&gt;
			local subsplit = rsplit(subpair, &amp;quot;/&amp;quot;)&lt;br /&gt;
			text = rsub(text, subsplit[1], subsplit[2])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return export.tr(text, nil, nil, jo_accent, noadj, noshto, forceadj)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--for adjectives, pronouns&lt;br /&gt;
function export.tr_adj(text, jo_accent)&lt;br /&gt;
	if type(text) == &amp;quot;table&amp;quot; then -- called directly from a template&lt;br /&gt;
		jo_accent = ine(text.args.jo_accent)&lt;br /&gt;
		text = text.args[1]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- we have to include &amp;quot;forceadj&amp;quot; because typically when tr_adj() is called&lt;br /&gt;
	-- from the noun or adjective modules, it&amp;#039;s called with suffix ого, which&lt;br /&gt;
	-- would otherwise trigger the exceptional case and be transliterated as ogo&lt;br /&gt;
	return export.tr(text, nil, nil, jo_accent, false,&lt;br /&gt;
		&amp;quot;noshto&amp;quot;, &amp;quot;forceadj&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Melinoë</name></author>
	</entry>
</feed>