Permanently protected module
From Wikipedia, the free encyclopedia


local p = {}



local macron = mw.ustring.char(0x304)

local breve = mw.ustring.char(0x306)

local rough = mw.ustring.char(0x314)

local smooth = mw.ustring.char(0x313)

local diaeresis = mw.ustring.char(0x308)

local acute = mw.ustring.char(0x301)

local grave = mw.ustring.char(0x300)

local circumflex = mw.ustring.char(0x342)

local Latin_circumflex = mw.ustring.char(0x302)

local subscript = mw.ustring.char(0x345)

local macron_circumflex = macron .. diaeresis .. '?' .. Latin_circumflex



local is_velar = { 'κ' = true, 'γ' = true, 'χ' = true, 'ξ' = true, }



local UTF8_char = "[%z\1-\127\194-\244][\128-\191]*"

local basic_Greek = "[\206-\207][\128-\191]" -- excluding first line of Greek and Coptic block: ͰͱͲͳʹ͵Ͷͷͺͻͼͽ;Ϳ



local info = {}



-- The tables are shared among different characters so that they can be checked

-- for equality if needed, and to use less space.

local vowel = { vowel = true, diacritic_seat = true }

local iota = { vowel = true, diacritic_seat = true, offglide = true }

local upsilon = { vowel = true, diacritic_seat = true, offglide = true }

-- Technically rho is only a seat for rough or smooth breathing.

local rho = { consonant = true, diacritic_seat = true }

local consonant = { consonant = true }

local diacritic = { diacritic = true }

-- Needed for equality comparisons.

local breathing = { diacritic = true }



local function add_info(characters, t)

	if type(characters) == "string" then

		for character in string.gmatch(characters, UTF8_char) do

			infocharacter = t

		end

	else

		for _, character in ipairs(characters) do

			infocharacter = t

		end

	end

end



add_info({ macron, breve,

		diaeresis,

		acute, grave, circumflex,

		subscript,

	}, diacritic)



add_info({rough, smooth}, breathing)

add_info("ΑΕΗΟΩαεηοω", vowel)

add_info("Ιι", iota)

add_info("Υυ", upsilon)

add_info("ΒΓΔΖΘΚΛΜΝΞΠΡΣΤΦΧΨϜϘϺϷͶϠβγδζθκλμνξπρσςτφχψϝϙϻϸͷϡ", consonant)

add_info("Ρρ", rho)



local not_recognized = {}

setmetatable(info, { __index =

	function()

		return not_recognized

	end

})



local function quote(str)

	return "“" ..  str .. "”"

end



local correspondences = {

	-- Vowels

	"α" = "a",

	"ε" = "e",

	"η" = "e" .. macron,

	"ι" = "i",

	"ο" = "o",

	"υ" = "u",

	"ω" = "o" .. macron,



	-- Consonants

	"β" = "b",

	"γ" = "g",

	"δ" = "d",

	"ζ" = "z",

	"θ" = "th",

	"κ" = "k",

	"λ" = "l",

	"μ" = "m",

	"ν" = "n",

	"ξ" = "x",

	"π" = "p",

	"ρ" = "r",

	"σ" = "s",

	"ς" = "s",

	"τ" = "t",

	"φ" = "ph",

	"ψ" = "ps",

	

	-- Archaic letters

	"ϝ" = "w",

	"ϻ" = "ś",

	"ϙ" = "q",

	"ϡ" = "š",

	"ͷ" = "v",

	

	-- Diacritics

	smooth = '',

	rough = '', -- h is added below in the `transliterate` function.

	breve = '',

}



local ALA_LC = {

	"χ" = "ch",

	acute = '',

	grave = '',

	circumflex = '',

	subscript = '',

	diaeresis = '',

	macron = '',

}



local Wiktionary_transliteration = {

	"χ" = "kh",

	circumflex = Latin_circumflex,

	subscript = 'i',

}



local function add_index_metamethod(t, index_metamethod)

	local mt = getmetatable(t)

	if not mt then

		mt = {}

		setmetatable(t, mt)

	end

	mt.__index = index_metamethod

end



--[=[

		This breaks a word into meaningful "tokens", which are

		individual letters or diphthongs with their diacritics.

		Used by [[Module:grc-accent]] and [[Module:grc-pronunciation]].

--]=]

local function tokenize(text)

	local tokens, vowel_info, prev_info = {}, {}, {}

	local token_i = 1

	local prev

	for character in string.gmatch(mw.ustring.toNFD(text), UTF8_char) do

		local curr_info = infocharacter

		-- Split vowels between tokens if not a diphthong.

		if curr_info.vowel then

			if prev and (not (curr_info.offglide and prev_info.vowel)

					-- υυ → υ, υ

					-- ιυ → ι, υ

					or prev_info.offglide and curr_info == upsilon) then

				token_i = token_i + 1

			end

			tokenstoken_i = (tokenstoken_i or "") .. character

			table.insert(vowel_info, { index = token_i })

		elseif curr_info.diacritic then

			tokenstoken_i = (tokenstoken_i or "") .. character

			if prev_info.vowel or prev_info.diacritic then

				if character == diaeresis then

					-- Current token is vowel, vowel, possibly other diacritics,

					-- and a diaeresis.

					-- Split the current token into two:

					-- the first letter, then the second letter plus any diacritics.

					local previous_vowel, vowel_with_diaeresis = string.match(tokenstoken_i], "^(" .. basic_Greek .. ")(" .. basic_Greek .. ".+)")

					if previous_vowel then

						tokenstoken_i], tokenstoken_i + 1 = previous_vowel, vowel_with_diaeresis

						token_i = token_i + 1

					end

				end

			elseif prev_info == rho then

				if curr_info ~= breathing then

					return string.format("The character %s cannot have the accent %s on it.", prev, "◌" .. character)

				end

			else

				error("The character " .. quote(prev) .. " cannot have a diacritic on it.")

			end

		elseif curr_info == rho then

			if prev and not (prev_info == breathing and infostring.match(tokenstoken_i], "^" .. basic_Greek)] == rho) then

				token_i = token_i + 1

			end

			tokenstoken_i = (tokenstoken_i or "") .. character

		else

			if prev then

				token_i = token_i + 1

			end

			tokenstoken_i = (tokenstoken_i or "") .. character

		end

		prev = character

		prev_info = curr_info

	end

	return tokens

end



function p.transliterate(text, system)

	add_index_metamethod(correspondences, system == "ALA-LC" and ALA_LC or Wiktionary_transliteration)

	

	if text == '῾' then

		return 'h'

	end

	

	text = mw.ustring.toNFD(text)

	

	--[[

		Replace semicolon or Greek question mark with regular question mark,

		except after an ASCII alphanumeric character (to avoid converting

		semicolons in HTML entities).

	--]]

	text = mw.ustring.gsub(text, "([^A-Za-z0-9])[;" .. mw.ustring.char(0x37E) .. "]", "%1?")

	

	-- Handle the middle dot. It is equivalent to semicolon or colon, but semicolon is probably more common.

	text = text:gsub("·", ";")

	

	local tokens = tokenize(text)



	--now read the tokens

	local output = {}

	for i, token in pairs(tokens) do

		-- substitute each character in the token for its transliteration

		local translit = string.gsub(mw.ustring.lower(token), UTF8_char, correspondences)

		

		if token == 'γ' and is_velartokensi + 1]] then

			-- γ before a velar should be <n>

			translit = 'n'

		elseif token == 'ρ' and tokensi - 1 == 'ρ' then

			-- ρ after ρ should be <rh>

			translit = 'rh'

		elseif system == "Wiktionary" and mw.ustring.find(token, '^[αΑ].*' .. subscript .. '$') then

			-- add macron to ᾳ

			translit = mw.ustring.gsub(translit, '([aA])', '%1' .. macron)

		end

		

		if token:find(rough) then

			if mw.ustring.find(token, '[Ρρ]') then

				translit = translit .. 'h'

			else -- vowel

				translit = 'h' .. translit

			end

		end

		

		if system == "ALA-LC" and mw.ustring.find(token, '^[υΥ][^ιΙ]*$') then

			translit = translit:gsub('u', 'y'):gsub('U', 'Y')

		end

		

		-- Remove macron from a vowel that has a circumflex.

		if mw.ustring.find(translit, macron_circumflex) then

			translit = translit:gsub(macron, '')

		end

		

		-- Capitalize first character of transliteration.

		if token ~= mw.ustring.lower(token) then

			translit = mw.ustring.gsub(translit, "^.", mw.ustring.upper)

		end

		

		table.insert(output, translit)

	end

	

	return table.concat(output)

end



function p.translit(frame)

	local text = frame.args1 or frame:getParent().args1

	

	local system = frame.args.system

	if system == nil or system == "" then

		system = "Wiktionary"

	elseif not (system == "ALA-LC" or system == "Wiktionary") then

		error('Transliteration system in |system= not recognized; choose between "ALA-LC" and "Wiktionary"')

	end

	

	local transliteration = p.transliterate(text, system)

	return '<span title="Ancient Greek transliteration" lang="grc-Latn"><i>' .. transliteration .. '</i></span>'

end



function p.bare_translit(frame)

	return p.transliterate(frame.args1 or frame:getParent().args1])

end



return p
Permanently protected module
From Wikipedia, the free encyclopedia


local p = {}



local macron = mw.ustring.char(0x304)

local breve = mw.ustring.char(0x306)

local rough = mw.ustring.char(0x314)

local smooth = mw.ustring.char(0x313)

local diaeresis = mw.ustring.char(0x308)

local acute = mw.ustring.char(0x301)

local grave = mw.ustring.char(0x300)

local circumflex = mw.ustring.char(0x342)

local Latin_circumflex = mw.ustring.char(0x302)

local subscript = mw.ustring.char(0x345)

local macron_circumflex = macron .. diaeresis .. '?' .. Latin_circumflex



local is_velar = { 'κ' = true, 'γ' = true, 'χ' = true, 'ξ' = true, }



local UTF8_char = "[%z\1-\127\194-\244][\128-\191]*"

local basic_Greek = "[\206-\207][\128-\191]" -- excluding first line of Greek and Coptic block: ͰͱͲͳʹ͵Ͷͷͺͻͼͽ;Ϳ



local info = {}



-- The tables are shared among different characters so that they can be checked

-- for equality if needed, and to use less space.

local vowel = { vowel = true, diacritic_seat = true }

local iota = { vowel = true, diacritic_seat = true, offglide = true }

local upsilon = { vowel = true, diacritic_seat = true, offglide = true }

-- Technically rho is only a seat for rough or smooth breathing.

local rho = { consonant = true, diacritic_seat = true }

local consonant = { consonant = true }

local diacritic = { diacritic = true }

-- Needed for equality comparisons.

local breathing = { diacritic = true }



local function add_info(characters, t)

	if type(characters) == "string" then

		for character in string.gmatch(characters, UTF8_char) do

			infocharacter = t

		end

	else

		for _, character in ipairs(characters) do

			infocharacter = t

		end

	end

end



add_info({ macron, breve,

		diaeresis,

		acute, grave, circumflex,

		subscript,

	}, diacritic)



add_info({rough, smooth}, breathing)

add_info("ΑΕΗΟΩαεηοω", vowel)

add_info("Ιι", iota)

add_info("Υυ", upsilon)

add_info("ΒΓΔΖΘΚΛΜΝΞΠΡΣΤΦΧΨϜϘϺϷͶϠβγδζθκλμνξπρσςτφχψϝϙϻϸͷϡ", consonant)

add_info("Ρρ", rho)



local not_recognized = {}

setmetatable(info, { __index =

	function()

		return not_recognized

	end

})



local function quote(str)

	return "“" ..  str .. "”"

end



local correspondences = {

	-- Vowels

	"α" = "a",

	"ε" = "e",

	"η" = "e" .. macron,

	"ι" = "i",

	"ο" = "o",

	"υ" = "u",

	"ω" = "o" .. macron,



	-- Consonants

	"β" = "b",

	"γ" = "g",

	"δ" = "d",

	"ζ" = "z",

	"θ" = "th",

	"κ" = "k",

	"λ" = "l",

	"μ" = "m",

	"ν" = "n",

	"ξ" = "x",

	"π" = "p",

	"ρ" = "r",

	"σ" = "s",

	"ς" = "s",

	"τ" = "t",

	"φ" = "ph",

	"ψ" = "ps",

	

	-- Archaic letters

	"ϝ" = "w",

	"ϻ" = "ś",

	"ϙ" = "q",

	"ϡ" = "š",

	"ͷ" = "v",

	

	-- Diacritics

	smooth = '',

	rough = '', -- h is added below in the `transliterate` function.

	breve = '',

}



local ALA_LC = {

	"χ" = "ch",

	acute = '',

	grave = '',

	circumflex = '',

	subscript = '',

	diaeresis = '',

	macron = '',

}



local Wiktionary_transliteration = {

	"χ" = "kh",

	circumflex = Latin_circumflex,

	subscript = 'i',

}



local function add_index_metamethod(t, index_metamethod)

	local mt = getmetatable(t)

	if not mt then

		mt = {}

		setmetatable(t, mt)

	end

	mt.__index = index_metamethod

end



--[=[

		This breaks a word into meaningful "tokens", which are

		individual letters or diphthongs with their diacritics.

		Used by [[Module:grc-accent]] and [[Module:grc-pronunciation]].

--]=]

local function tokenize(text)

	local tokens, vowel_info, prev_info = {}, {}, {}

	local token_i = 1

	local prev

	for character in string.gmatch(mw.ustring.toNFD(text), UTF8_char) do

		local curr_info = infocharacter

		-- Split vowels between tokens if not a diphthong.

		if curr_info.vowel then

			if prev and (not (curr_info.offglide and prev_info.vowel)

					-- υυ → υ, υ

					-- ιυ → ι, υ

					or prev_info.offglide and curr_info == upsilon) then

				token_i = token_i + 1

			end

			tokenstoken_i = (tokenstoken_i or "") .. character

			table.insert(vowel_info, { index = token_i })

		elseif curr_info.diacritic then

			tokenstoken_i = (tokenstoken_i or "") .. character

			if prev_info.vowel or prev_info.diacritic then

				if character == diaeresis then

					-- Current token is vowel, vowel, possibly other diacritics,

					-- and a diaeresis.

					-- Split the current token into two:

					-- the first letter, then the second letter plus any diacritics.

					local previous_vowel, vowel_with_diaeresis = string.match(tokenstoken_i], "^(" .. basic_Greek .. ")(" .. basic_Greek .. ".+)")

					if previous_vowel then

						tokenstoken_i], tokenstoken_i + 1 = previous_vowel, vowel_with_diaeresis

						token_i = token_i + 1

					end

				end

			elseif prev_info == rho then

				if curr_info ~= breathing then

					return string.format("The character %s cannot have the accent %s on it.", prev, "◌" .. character)

				end

			else

				error("The character " .. quote(prev) .. " cannot have a diacritic on it.")

			end

		elseif curr_info == rho then

			if prev and not (prev_info == breathing and infostring.match(tokenstoken_i], "^" .. basic_Greek)] == rho) then

				token_i = token_i + 1

			end

			tokenstoken_i = (tokenstoken_i or "") .. character

		else

			if prev then

				token_i = token_i + 1

			end

			tokenstoken_i = (tokenstoken_i or "") .. character

		end

		prev = character

		prev_info = curr_info

	end

	return tokens

end



function p.transliterate(text, system)

	add_index_metamethod(correspondences, system == "ALA-LC" and ALA_LC or Wiktionary_transliteration)

	

	if text == '῾' then

		return 'h'

	end

	

	text = mw.ustring.toNFD(text)

	

	--[[

		Replace semicolon or Greek question mark with regular question mark,

		except after an ASCII alphanumeric character (to avoid converting

		semicolons in HTML entities).

	--]]

	text = mw.ustring.gsub(text, "([^A-Za-z0-9])[;" .. mw.ustring.char(0x37E) .. "]", "%1?")

	

	-- Handle the middle dot. It is equivalent to semicolon or colon, but semicolon is probably more common.

	text = text:gsub("·", ";")

	

	local tokens = tokenize(text)



	--now read the tokens

	local output = {}

	for i, token in pairs(tokens) do

		-- substitute each character in the token for its transliteration

		local translit = string.gsub(mw.ustring.lower(token), UTF8_char, correspondences)

		

		if token == 'γ' and is_velartokensi + 1]] then

			-- γ before a velar should be <n>

			translit = 'n'

		elseif token == 'ρ' and tokensi - 1 == 'ρ' then

			-- ρ after ρ should be <rh>

			translit = 'rh'

		elseif system == "Wiktionary" and mw.ustring.find(token, '^[αΑ].*' .. subscript .. '$') then

			-- add macron to ᾳ

			translit = mw.ustring.gsub(translit, '([aA])', '%1' .. macron)

		end

		

		if token:find(rough) then

			if mw.ustring.find(token, '[Ρρ]') then

				translit = translit .. 'h'

			else -- vowel

				translit = 'h' .. translit

			end

		end

		

		if system == "ALA-LC" and mw.ustring.find(token, '^[υΥ][^ιΙ]*$') then

			translit = translit:gsub('u', 'y'):gsub('U', 'Y')

		end

		

		-- Remove macron from a vowel that has a circumflex.

		if mw.ustring.find(translit, macron_circumflex) then

			translit = translit:gsub(macron, '')

		end

		

		-- Capitalize first character of transliteration.

		if token ~= mw.ustring.lower(token) then

			translit = mw.ustring.gsub(translit, "^.", mw.ustring.upper)

		end

		

		table.insert(output, translit)

	end

	

	return table.concat(output)

end



function p.translit(frame)

	local text = frame.args1 or frame:getParent().args1

	

	local system = frame.args.system

	if system == nil or system == "" then

		system = "Wiktionary"

	elseif not (system == "ALA-LC" or system == "Wiktionary") then

		error('Transliteration system in |system= not recognized; choose between "ALA-LC" and "Wiktionary"')

	end

	

	local transliteration = p.transliterate(text, system)

	return '<span title="Ancient Greek transliteration" lang="grc-Latn"><i>' .. transliteration .. '</i></span>'

end



function p.bare_translit(frame)

	return p.transliterate(frame.args1 or frame:getParent().args1])

end



return p

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook