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