본문으로 이동

모듈:syllables

위키낱말사전, 말과 글의 누리

이 모듈에 대한 설명문서는 모듈:syllables/설명문서에서 만들 수 있습니다

local export = {}

local m_str_utils = require("Module:string utilities")

local gsub = m_str_utils.gsub
local match = m_str_utils.match
local toNFD = mw.ustring.toNFD
local U = m_str_utils.char

local diphthongs = mw.loadData("Module:IPA/data").diphthongs
local vowels = mw.loadData("Module:IPA/data/symbols").vowels .. "ᵻ" .. "ᵿ"

--[[ 현재로서는 사용할 곳이 없지만 흥미로운 목록입니다.
	이는 음성적 전사에 사용될 수 있습니다.
	모음에 추가된 발음 구별 기호:
	윗쪽 역부호, 아랫쪽 역부호,
	위로 붙이는 표시, 아래로 붙이는 표시,
	왼쪽 붙이는 표시, 오른쪽 붙이는 표시,
	위쪽 분음 기호, 아랫쪽 분음 기호,
	오른쪽 반고리, 왼쪽 반고리,
	아래쪽 더하기 기호, 아래쪽 빼기 기호,
	위쪽 결합 X, 구르트기 갈고리,
	윗쪽 물결표, 아랫쪽 물결표
	결합형 타이 (결합형 이중 짧은 부호), 아랫쪽 결합형 타이
	]]
local diacritics = U(
	0x311, 0x32F,
	0x31D, 0x31E,
	0x318, 0x319,
	0x308, 0x324,
	0x339, 0x31C,
	0x31F, 0x320,
	0x33D, 0x2DE,
	0x303, 0x330,
	0x361, 0x35C
)

--[[
결합형 억양 및 음조 표시, 곡절 악센트
]]--
local tone = "[" .. U(0x341, 0x340, 0x302) .. "]"
local nonsyllabicDiacritics = U(0x311, 0x32F)
local syllabicDiacritics = U(0x0329, 0x030D)
local ties = U(0x361, 0x35C)

-- 길이, 반길이, 매우 짧음
local lengthDiacritics = U(0x2D0, 0x2D1, 0x306)
local vowel = "[" .. vowels .. "]" .. tone .. "?"
local tie = "[" .. ties .. "]"
local nonsyllabicDiacritic = "[" .. nonsyllabicDiacritics .. "]"
local syllabicDiacritic = "[" .. syllabicDiacritics .. "]"

local UTF8Char = "[\1-\127\194-\244][\128-\191]*"


function export.getVowels(remainder, lang)
	if string.find(remainder, "^[%[/]?%-") or string.find(remainder, "%-[%[/]?$") then
		return nil
	end	-- 전사 시작 또는 끝에 하이픈이 있는 경우, 음절 수를 세지 않습니다.
	
	local count = 0
	local diphs = diphthongs[lang:getCode()] or {}
	
	remainder = toNFD(remainder)
	remainder = string.gsub(remainder, "%((.*)%)", "%1") -- 괄호 제거.

	while remainder ~= "" do
		-- 비음절 모음 무시
		remainder = gsub(remainder, "^" .. vowel .. nonsyllabicDiacritic, "")
		
		local m =
			match(remainder, "^." .. syllabicDiacritic) or  -- 음절 자음
			match(remainder, "^" .. vowel .. tie .. vowel)  -- 결합형 타이
		
		-- 인식된 이중모음으로 시작합니까?
		for _, diph in ipairs(diphs) do
			if m then
				break
			end
			
			m = m or match(remainder, "^" .. diph)
		end
		
		-- 아직 아무것도 찾지 못했다면, 단일 모음에 대해 일치시킵니다.
		m = m or match(remainder, "^" .. vowel)
		
		if m then
			-- 모음을 찾았으니 추가합니다.
			count = count + 1
			remainder = string.sub(remainder, #m + 1)
		else
			-- 모음을 찾지 못했으니 건너뜁니다.
			remainder = string.gsub(remainder, "^" .. UTF8Char, "")
		end
	end
	
	if count ~= 0 then return count end
	
	return nil
	
end

function export.countVowels2Test(frame)
	local params = {
		[1] = {required = true},
		[2] = {default = ""},
	}
	
	local args = require("Module:parameters").process(frame.args, params)
	
	local lang = require("Module:languages").getByCode(args[1]) or require("Module:languages").err(args[1], 1)
	
	local count = export.getVowels(args[2], lang)
	
	return '텍스트 "' .. args[2] .. '"에는 ' .. count .. '개의 모음이 있습니다.'
end

local function countVowels(text)
	text = toNFD(text) or error("유효하지 않은 UTF-8")
	
	local _, count = gsub(text, vowel, "")
	local _, sequenceCount = gsub(text, vowel.."+", "")
	local _, nonsyllabicCount = gsub(text, vowel .. nonsyllabicDiacritic, "")
	local _, tieCount = gsub(text, vowel .. tie .. vowel, "")
	
	local diphthongCount = count - (nonsyllabicCount + tieCount)
	
	return count, sequenceCount, diphthongCount
end

local function countDiphthongs(text, lang)
	text = toNFD(text) or error("유효하지 않은 UTF-8")
	
	local diphthongs = diphthongs[lang:getCode()] or {}
	
	local _, count
	local total = 0
	
	if diphthongs then
		for i, diphthong in pairs(diphthongs) do
			_, count = gsub(text, diphthong, "")
			total = total + count
		end
	end
	
	return total
end

function export.countVowels(frame)
	local params = {
		[1] = {default = ""},
	}
	
	local args = require("Module:parameters").process(frame.args, params)
	
	local count, sequenceCount, diphthongCount = countVowels(args[1])
	
	local outputs = {}
	table.insert(outputs, (count or '알 수 없는 수의') .. ' 모음')
	table.insert(outputs, (sequenceCount or '알 수 없는 수의') .. ' 모음 연속')
	table.insert(outputs, (diphthongCount or '알 수 없는 수의') .. ' 모음 또는 모음과 이중모음')
	
	return '텍스트 "' .. args[1] .. '"에는 ' .. mw.text.listToText(outputs) .. "이(가) 포함되어 있습니다."
end

function export.countVowelsDiphthongs(frame)
	local params = {
		[1] = {required = true},
		[2] = {default = ""},
	}
	
	local args = require("Module:parameters").process(frame.args, params)
	
	local lang = require("Module:languages").getByCode(args[1]) or require("Module:languages").err(args[1], 1)
	
	local vowels = countVowels(args[2])
	local count = vowels - countDiphthongs(args[2], lang) or 0
	
	local out = '텍스트 "' .. args[2] .. '"에는 ' .. (count or '알 수 없는 수의')
	
	if count == 1 then
		out = out .. ' 모음 또는 이중모음이 있습니다.'
	else
		out = out .. ' 모음 또는 이중모음이 있습니다.'
	end
	
	return out
end

return export