모듈:script utilities

관련 모듈

편집

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

local require_when_needed = require("Module:utilities/require when needed")
local concat = table.concat
local find = m_string_utils.find
local gsub = m_string_utils.gsub
local insert = table.insert
local process_params = require_when_needed("Module:parameters", "process")
local toNFD = mw.ustring.toNFD
local u = m_string_utils.char

local export = {}

--[=[
	Modules used:
	[[Module:script utilities/data]]
	[[Module:scripts]]
	[[Module:senseid]] (only when id's present)
	[[Module:string utilities]] (only when hyphens in Korean text or spaces in vertical text)
	[[Module:languages]]
	[[Module:parameters]]
	[[Module:utilities]]
	[[Module:debug/track]]
]=]

-- Implements [[Template:lang]]
function export.lang_t(frame)
    local args = frame:getParent().args
    NAMESPACE = mw.title.getCurrentTitle().nsText
    
    local lang = args[1]; if lang == "" then lang = nil end
    local text = args[2] or ""
    local sc = args["sc"]; if sc == "" then sc = nil end
    local face = args["face"]; if face == "" then face = nil end
    
-- 언어코드가 지정되지 않았을 경우 오류 스크립트를 호출합니다.
    lang = lang or (NAMESPACE == "Template" and "und") or error("IOS 언어코드가 지정되지 않았습니다. Please pass parameter 1 to the template.")
    lang = require("모듈:languages").getByCode(lang) or error("The language code \"" .. lang .. "\" is not valid.")
    sc = (sc and (require("모듈:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")) or nil)
    
    return export.tag_text(text, lang, sc, face)
end

-- Wrap text in the appropriate HTML tags with language and script class.
function export.tag_text(text, lang, sc, face)
    if not sc then
        sc = require("모듈:scripts").findBestScript(text, lang)
    end
    
    -- Add a script wrapper
    if face == "term" then
        return '<i class="' .. sc:getCode() .. ' mention" lang="' .. lang:getCode() .. '">' .. text .. '</i>'
    elseif face == "head" then
        return '<strong class="' .. sc:getCode() .. ' headword" lang="' .. lang:getCode() .. '">' .. text .. '</strong>'
    elseif face == "bold" then
        return '<b class="' .. sc:getCode() .. '" lang="' .. lang:getCode() .. '">' .. text .. '</b>'
    elseif face == nil then
        return '<span class="' .. sc:getCode() .. '" lang="' .. lang:getCode() .. '">' .. text .. '</span>'
    else
        error("Invalid script face \"" .. face .. "\".")
    end
end

--[==[Tags the transliteration for given text {translit} and language {lang}. It will add the language, script subtag (as defined in [https://www.rfc-editor.org/rfc/bcp/bcp47.txt BCP 47 2.2.3]) and [https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir dir] (directional) attributes as needed.
The optional <code>kind</code> parameter can be one of the following:
; {{code|lua|"term"}}
: tag transliteration for {{temp|mention}}
; {{code|lua|"usex"}}
: tag transliteration for {{temp|usex}}
; {{code|lua|"head"}}
: tag transliteration for {{temp|head}}
; {{code|lua|"default"}}
: default
The optional <code>attributes</code> parameter is used to specify additional HTML attributes for the tag.]==]
function export.tag_translit(translit, lang, kind, attributes, is_manual)
	if type(lang) == "table" then
		-- FIXME: Do better support for etym languages; see https://www.rfc-editor.org/rfc/bcp/bcp47.txt
		lang = lang.getFullCode and lang:getFullCode()
			or error("Second argument to tag_translit should be a language code or language object.")
	end
	
	local data = mw.loadData("Module:script utilities/data").translit[kind or "default"]
	
	local opening_tag = {}
	
	insert(opening_tag, data.tag)
	if lang == "ja" then
		insert(opening_tag, 'class="' .. (data.classes and data.classes .. " " or "") .. (is_manual and "manual-tr " or "") .. 'tr"')
	else
		insert(opening_tag, 'lang="' .. lang .. '-Latn"')
		insert(opening_tag, 'class="' .. (data.classes and data.classes .. " " or "") .. (is_manual and "manual-tr " or "") .. 'tr Latn"')
	end
	
	if data.dir then
		insert(opening_tag, 'dir="' .. data.dir .. '"')
	end
	
	insert(opening_tag, attributes)
	
	return "<" .. concat(opening_tag, " ") .. ">" .. translit .. "</" .. data.tag .. ">"
end

function export.tag_transcription(transcription, lang, kind, attributes)
	if type(lang) == "table" then
		-- FIXME: Do better support for etym languages; see https://www.rfc-editor.org/rfc/bcp/bcp47.txt
		lang = lang.getFullCode and lang:getFullCode()
			or error("Second argument to tag_transcription should be a language code or language object.")
	end
	
	local data = mw.loadData("Module:script utilities/data").transcription[kind or "default"]
	
	local opening_tag = {}
	
	insert(opening_tag, data.tag)
	if lang == "ja" then
		insert(opening_tag, 'class="' .. (data.classes and data.classes .. " " or "") .. 'ts"')
	else
		insert(opening_tag, 'lang="' .. lang .. '-Latn"')
		insert(opening_tag, 'class="' .. (data.classes and data.classes .. " " or "") .. 'ts Latn"')
	end
	
	if data.dir then
		insert(opening_tag, 'dir="' .. data.dir .. '"')
	end
	
	insert(opening_tag, attributes)
	
	return "<" .. concat(opening_tag, " ") .. ">" .. transcription .. "</" .. data.tag .. ">"	
end

-- Add a notice to request the native script of a word
function export.request_script(lang, sc, usex, nocat, sort_key)
	local scripts = lang.getScripts and lang:getScripts() or error('The language "' .. lang:getCode() .. '" does not have the method getScripts. It may be unwritten.')
	
	-- By default, request for "native" script
	local cat_script = "native"
	local disp_script = "script"
	
	-- If the script was not specified, and the language has only one script, use that.
	if not sc and #scripts == 1 then
		sc = scripts[1]
	end
	
	-- Is the script known?
	if sc and sc:getCode() ~= "None" then
		-- If the script is Latin, return nothing.
		if export.is_Latin_script(sc) then
			return ""
		end
		
		if (not scripts[1]) or sc:getCode() ~= scripts[1]:getCode() then
			disp_script = sc:getCanonicalName()
		end
		
		-- The category needs to be specific to script only if there is chance of ambiguity. This occurs when when the language has multiple scripts (or with codes such as "und").
		if (not scripts[1]) or scripts[2] then
			cat_script = sc:getCanonicalName()
		end
	else
		-- The script is not known.
		-- Does the language have at least one non-Latin script in its list?
		local has_nonlatin = false
		
		for i, val in ipairs(scripts) do
			if not export.is_Latin_script(val) then
				has_nonlatin = true
				break
			end
		end
		
		-- If there are no non-Latin scripts, return nothing.
		if not has_nonlatin then
			return ""
		end
	end
	
	local category
	
	if usex then
		local usex_type = usex == "quote" and "quotations" or "usage examples"
		-- Etymology languages have their own categories, whose parents are the regular language.
		category = "Requests for " .. cat_script .. " script in " .. lang:getCanonicalName() .. " " .. usex_type
	else
		category = "Requests for " .. cat_script .. " script for " .. lang:getCanonicalName() .. " terms"
	end
	
	return "<small>[" .. disp_script .. " needed]</small>" ..
		(nocat and "" or require("Module:utilities").format_categories({category}, lang, sort_key))
end


function export.template_rfscript(frame)
    local args = frame.args
    local lang = args[1] or error("The first parameter (language code) has not been given")
    local sc = args["sc"]; if sc == "" then sc = nil end
    lang = require("모듈:languages").getByCode(lang) or error("The language code \"" .. lang .. "\" is not valid.")
    sc = (sc and (require("모듈:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")) or nil)
    
    local ret = export.request_script(lang, sc)
    
    if ret == "" then
        error("This language is written in the Latin alphabet. It does not need a native script.")
    else
        return ret
    end
end

function is_Latin_script(sc)
    return (sc:getCode():find("Latn", nil, true)) or sc:getCode() == "Latinx"
end

function export.checkScript(text, scriptCode, result)
	local scriptObject = require("Module:scripts").getByCode(scriptCode)
	
	if not scriptObject then
		error('The script code "' .. scriptCode .. '" is not recognized.')
	end
	
	local originalText = text
	
	-- Remove non-letter characters.
	text = gsub(text, "%A+", "")
	
	-- Remove all characters of the script in question.
	text = gsub(text, "[" .. scriptObject:getCharacters() .. "]+", "")
	
	if text ~= "" then
		if type(result) == "string" then
			error(result)
		else
			error('The text "' .. originalText .. '" contains the letters "' .. text .. '" that do not belong to the ' .. scriptObject:getDisplayForm() .. '.', 2)
		end
	end
end

return export