모듈:category tree/topic
보이기
이 모듈에 대한 설명문서는 모듈:category tree/topic/설명문서에서 만들 수 있습니다
local raw_handlers = {}
local raw_categories = {}
--[=[
이 모듈은 주제 분류 하위 시스템을 구현합니다.
현재는 언어별 및 포괄 주제 분류를 모두 처리하는 단일 원시 핸들러와,
이에 대응하는 시소러스 분류 핸들러로 구현되어 있습니다.
최상위 주제 분류인 [[:분류:모든 주제]]는 특별하며 별도의 원시 분류로 처리될 수 있지만,
현재는 원시 주제 핸들러의 일부로 처리됩니다. 최상위 시소러스 분류인 [[:분류:시소러스]]는
실제로 원시 분류로 처리됩니다.
]=]
local functions_module = "Module:fun"
local labels_utilities_module = "Module:labels/utilities"
local languages_module = "Module:languages"
local string_pattern_escape_module = "Module:string/patternEscape"
local string_replacement_escape_module = "Module:string/replacementEscape"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local ko_module
local topic_data_module = "Module:category tree/topic/data"
local topic_utilities_module = "Module:category tree/topic/utilities"
local thesaurus_data_module = "Module:category tree/topic/thesaurus data"
local concat = table.concat
local insert = table.insert
local dump = mw.dumpObject
local is_callable = require(functions_module).is_callable
local pattern_escape = require(string_pattern_escape_module)
local replacement_escape = require(string_replacement_escape_module)
local split = require(string_utilities_module).split
local type_data = {
["related-to"] = {
desc_func = function(topic)
ko_module = ko_module or require("Module:ko")
-- '와/과' 조사를 자동으로 처리합니다.
return ko_module.allomorphy(topic, "conj") .. " 관련된 낱말"
end,
additional = "'''참고''': 이 분류는 '관련' 분류입니다. {{{topic}}}와(과) 직접적으로 관련된 낱말을 포함해야 합니다. " ..
"단순히 부수적인 연관성만 있는 낱말은 포함하지 마십시오. " ..
"이 주제의 유형이나 사례에 해당하는 낱말은 종종 별도의 분류에 속한다는 점에 유의하십시오.",
},
set = {
desc_func = function(topic)
return topic .. "의 종류나 예시에 해당하는 낱말"
end,
additional = "'''참고''': 이 분류는 '집합' 분류입니다. {{{topic}}}에 단순히 관련된 낱말이 아닌, {{{topic}}} 자체에 해당하는 낱말을 포함해야 합니다. " ..
"더 일반적인 낱말(예: {{{topic}}}의 종류)이나 더 구체적인 낱말(예: 특정 {{{topic}}}의 명칭)을 포함할 수 있으나, " ..
"이러한 유형의 낱말들을 위한 관련 분류가 별도로 존재할 수 있습니다.",
},
name = {
desc_func = function(topic)
return topic .. "의 구체적인 명칭"
end,
additional = "'''참고''': 이 분류는 '명칭' 분류입니다. {{{topic}}}에 관련된 낱말이나 {{{topic}}}의 종류에 대한 일반적인 낱말이 아닌, " ..
"특정 {{{topic}}}의 명칭을 포함해야 합니다.",
},
type = {
desc_func = function(topic)
return topic .. "의 종류에 해당하는 낱말"
end,
additional = "'''참고''': 이 분류는 '유형' 분류입니다. {{{topic}}}에 관련된 낱말이나 특정 {{{topic}}}의 명칭이 아닌, " ..
"{{{topic}}}의 유형에 해당하는 낱말을 포함해야 합니다.",
},
grouping = {
desc_func = function(topic)
return topic .. "의 더 구체적인 변종에 관한 분류"
end,
additional = "'''참고''': 이 분류는 '그룹' 분류입니다. 어떠한 낱말도 직접 포함해서는 안 되며, " ..
"오직 하위 분류만을 포함해야 합니다. 만약 이 분류에 직접 포함된 낱말이 있다면, 적절한 하위 분류로 옮겨주십시오.",
},
toplevel = {
desc_func = function(topic) return "" end, -- 이 유형은 설명을 직접 지정함
additional = "'''참고''': 이 분류는 최상위 목록 분류입니다. 어떠한 낱말도 직접 포함해서는 안 되며, " ..
"오직 {{{topic}}}만을 포함해야 합니다.",
},
}
local function invalid_type(types)
local valid_types = {}
for typ, _ in pairs(type_data) do
insert(valid_types, ("'%s'"):format(typ))
end
error(("유효하지 않은 유형 '%s'. 쉼표로 구분된 다음 값 중 하나여야 합니다: %s")
:format(types, mw.text.listToText(valid_types)))
end
local function split_types(types)
types = types or "related-to"
local splitvals = split(types, "%s*,%s*")
for i, typ in ipairs(splitvals) do
-- FIXME: 임시 조치
if typ == "topic" then
typ = "related-to"
end
if not type_data[typ] then
invalid_type(types)
end
splitvals[i] = typ
end
return splitvals
end
local function gsub_escaping_replacement(str, from, to)
return (str:gsub(pattern_escape(from), replacement_escape(to)))
end
function ucfirst(txt)
local italics, raw_txt = txt:match("^('*)(.-)$")
return italics .. mw.getContentLanguage():ucfirst(raw_txt)
end
function lcfirst(txt)
local italics, raw_txt = txt:match("^('*)(.-)$")
return italics .. mw.getContentLanguage():lcfirst(raw_txt)
end
function convert_spec_to_string(data, desc)
if not desc then
return desc
end
local desc_type = type(desc)
if desc_type == "string" then
return desc
elseif desc_type == "number" then
return tostring(desc)
elseif not is_callable(desc) then
error("내부 오류: `desc`는 문자열, 숫자, 함수, 호출 가능한 테이블 또는 nil이어야 하나, " ..
desc_type .. " 유형이 전달되었습니다.")
end
desc = desc {
lang = data.lang,
sc = data.sc,
label = data.label,
category = data.category,
topdata = data.topdata,
}
if not desc then
return desc
end
desc_type = type(desc)
if desc_type == "string" then
return desc
end
error("내부 오류: `desc` 함수가 반환하는 값은 문자열 또는 nil이어야 하나, " .. desc_type .. " 유형이 반환되었습니다.")
end
local function get_and_cache(data, obj, key)
local val = convert_spec_to_string(data, obj[key])
obj[key] = val
return val
end
local function process_default(desc)
local stripped_desc = desc
local no_singularize, wikify, add_the
while true do
local new_stripped_desc = stripped_desc:match("^(.+) no singularize$")
if new_stripped_desc then
no_singularize = true
end
if not new_stripped_desc then
new_stripped_desc = stripped_desc:match("^(.+) wikify$")
if new_stripped_desc then
wikify = true
end
end
if not new_stripped_desc then
new_stripped_desc = stripped_desc:match("^(.+) with the$")
if new_stripped_desc then
add_the = true
end
end
if new_stripped_desc then
stripped_desc = new_stripped_desc
else
break
end
end
if stripped_desc == "default" then
return true, no_singularize, wikify, add_the
else
return false
end
end
local function format_desc(data, topic_word)
local desc_parts = {}
local types = split_types(data.topdata.type)
for _, typ in ipairs(types) do
-- 각 유형에 정의된 desc_func 함수를 호출하여 설명문을 생성합니다.
insert(desc_parts, type_data[typ].desc_func(topic_word))
end
return "{{{langname}}} " .. require("Module:table").serialCommaJoin(desc_parts) .. "."
end
local substitute_template_specs
local function format_displaytitle(data, include_lang_prefix, upcase)
local topdata, lang, label = data.topdata, data.lang, data.label
local displaytitle = substitute_template_specs(data, topdata.displaytitle)
if not displaytitle then
return nil
end
if upcase then
displaytitle = ucfirst(displaytitle)
end
if include_lang_prefix and lang then
displaytitle = ("%s:%s"):format(lang:getCode(), displaytitle)
end
return displaytitle
end
local function get_breadcrumb(data)
local topdata, lang, label = data.topdata, data.lang, data.label
local ret
if lang then
ret = topdata.breadcrumb or format_displaytitle(data, false, "upcase")
else
ret = topdata.umbrella and topdata.umbrella.breadcrumb or
topdata.breadcrumb or format_displaytitle(data, false, "upcase")
end
if not ret then
ret = label
end
if type(ret) == "string" or type(ret) == "number" then
ret = {name = ret}
end
local name = substitute_template_specs(data, ret.name)
local nocap = ret.nocap
return {name = name, nocap = nocap}
end
local function make_category_name(lang, label)
if lang then
return lang:getCode() .. ":" .. ucfirst(label)
else
return ucfirst(label)
end
end
local function replace_special_descriptions(data, desc)
if not desc then
return desc
end
if desc:find("^=") then
desc = desc:gsub("^=", "")
return format_desc(data, desc)
end
local is_default, no_singularize, wikify, add_the = process_default(desc)
if is_default then
local linked_label = require(topic_utilities_module).link_label(data.label, no_singularize, wikify)
if add_the then
linked_label = "the " .. linked_label
end
return format_desc(data, linked_label)
else
return desc
end
end
local function get_displaytitle_or_label(data)
return format_displaytitle(data, false) or data.label
end
local function process_default_add_the(data, topic)
local is_default, _, _, add_the = process_default(topic)
if is_default then
topic = get_displaytitle_or_label(data)
if add_the then
topic = "the " .. topic
end
end
return topic, is_default
end
substitute_template_specs = function(data, desc)
desc = convert_spec_to_string(data, desc)
if not desc then
return nil
end
local topdata, lang, label = data.topdata, data.lang, data.label
if desc:find("{{{umbrella_msg}}}") then
local catname = ucfirst(label)
desc = gsub_escaping_replacement(desc, "{{{umbrella_msg}}}",
"이 분류는 사전 항목을 직접 포함하지 않고 다른 분류만을 포함합니다. 하위 분류는 두 종류로 나뉩니다:\n\n" ..
"* \"{{{thespref}}}" .. "aa:" .. catname ..
"\"처럼 언어 코드가 앞에 붙는 하위 분류들은 특정 언어의 낱말들을 담는 분류입니다. " ..
"특히 [[:분류:{{{thespref}}}ko:" .. catname .. "]]에서 한국어 낱말을 찾아보실 수 있습니다.\n" ..
"* 언어 코드가 붙지 않는 하위 분류들은 이 분류와 마찬가지로 더 세부적인 주제를 다루는 분류들입니다."
)
end
if desc:find("{{{topic}}}") then
-- {{{topic}}}의 값을 계산합니다. 사용자가 `topic`을 지정하면 그 값을 사용합니다.
-- (포괄 분류인 경우 `umbrella.topic` 값을 별도로 허용하며, 없으면 `topic`으로 대체).
-- 그렇지 않으면, 설명이 'default'로 지정되었는지 확인하여 'the'를 붙일지 결정합니다.
-- 그 외의 경우, 레이블을 직접 사용합니다.
local topic = not lang and topdata.umbrella and topdata.umbrella.topic or topdata.topic
if topic then
topic = process_default_add_the(data, topic)
else
local desc_val
if not lang then
desc_val = topdata.umbrella and get_and_cache(data, topdata.umbrella, "description") or
get_and_cache(data, topdata, "umbrella_description")
end
desc_val = desc_val or get_and_cache(data, topdata, "description")
local defaulted_desc, is_default = process_default_add_the(data, desc_val)
if is_default then
topic = defaulted_desc
else
topic = get_displaytitle_or_label(data)
end
end
-- '와(과)' 조사가 필요한 경우를 감지하고 allomorphy 함수를 적용합니다.
desc = desc:gsub("{{{topic}}}와%(과%)", function()
ko_module = ko_module or require("Module:ko")
return ko_module.allomorphy(topic, "conj")
end)
-- 나머지 일반적인 경우는 그대로 치환합니다.
desc = gsub_escaping_replacement(desc, "{{{topic}}}", topic)
end
-- {{{thespref}}}를 시소러스 접두사로 치환합니다.
desc = desc:gsub("{{{thespref}}}", data.thesaurus_data and "시소러스:" or "")
return desc
end
local function process_box(data, def_topright_parts, val, pattern)
if not val then
return
end
local defval = ucfirst(data.label)
if type(val) ~= "table" then
val = {val}
end
for _, v in ipairs(val) do
if v == true then
insert(def_topright_parts, pattern:format(defval))
else
insert(def_topright_parts, pattern:format(v))
end
end
end
local function get_topright(data)
local topdata, lang = data.topdata, data.lang
local def_topright_parts = {}
-- {{wikipedia}}, {{commonscat}} 틀이 한국어 위키낱말사전에 존재해야 합니다.
process_box(data, def_topright_parts, topdata.wp, "{{위키백과|%s}}")
process_box(data, def_topright_parts, topdata.wpcat, "{{위키백과|분류=%s}}")
process_box(data, def_topright_parts, topdata.commonscat, "{{위키공용분류|%s}}")
local def_topright
if #def_topright_parts > 0 then
def_topright = concat(def_topright_parts, "\n")
end
if lang then
return substitute_template_specs(data, topdata.topright or def_topright)
else
return topdata.umbrella and substitute_template_specs(data, topdata.umbrella.topright) or
substitute_template_specs(data, def_topright)
end
end
local function remove_lang_params(desc)
desc = desc:gsub("^{{{langname}}} ", "")
desc = desc:gsub("{{{langcode}}}:", "")
desc = desc:gsub("^{{{langcode}}} ", "")
desc = desc:gsub("^{{{langcat}}} ", "")
return desc
end
local function get_additional_msg(data)
local types = split_types(data.topdata.type)
if #types > 1 then
local parts = {"'''참고''': 이것은 복합 유형 분류입니다. 다음 분류 유형에 해당하는 모든 낱말을 포함할 수 있습니다:"}
for i, typ in ipairs(types) do
insert(parts, ("* {{{topic}}}%s %s"):format(type_data[typ].desc_func and "" or " ", type_data[typ].desc_func and type_data[typ].desc_func(topic) or type_data[typ].desc, i == #types and "." or ";"))
end
insert(parts, "'''경고''': 이러한 분류는 강력히 지양되며, 각 유형별 분류로 분리되어야 합니다.")
return concat(parts, "\n")
elseif data.label == "모든 주제" then
return "'''참고''': 이것은 {{{langname}}}의 최상위 주제 분류입니다. 어떠한 낱말도 직접 포함해서는 안 되며, " ..
"유형별로 정리된 주제 분류 목록만을 포함해야 합니다."
else
return type_data[types[1]].additional
end
end
local function get_labels_categorizing(data)
local m_labels_utilities = require(labels_utilities_module)
return m_labels_utilities.format_labels_categorizing(
m_labels_utilities.find_labels_for_category(data.label, "topic", data.lang), nil, data.lang)
end
-- 설명, 그리고 설명 앞뒤에 오는 텍스트를 반환하는 함수.
-- 실제 텍스트 계산 작업(비용이 높을 수 있음)이 필요할 때만 수행되도록 클로저(closure) 형태로 반환.
local function get_description_additional_preceding(data)
local topdata, lang, label = data.topdata, data.lang, data.label
local desc, additional, preceding
-- This is kind of hacky, but it works for now.
local function postprocess_thesaurus(txt)
if not txt then return nil end
if not data.thesaurus_data then return txt end
txt = txt:gsub(" 낱말([ .,])", " 시소러스 항목%1")
return txt
end
if lang then
desc = function()
return postprocess_thesaurus(substitute_template_specs(data,
replace_special_descriptions(data, get_and_cache(data, topdata, "description"))))
end
preceding = topdata.preceding
additional = function()
local additional_parts = {}
if topdata.additional then
insert(additional_parts, topdata.additional)
end
if not data.thesaurus_data then
insert(additional_parts, get_additional_msg(data))
local labels_msg = get_labels_categorizing(data)
if labels_msg then
insert(additional_parts, labels_msg)
end
end
return postprocess_thesaurus(substitute_template_specs(data, concat(additional_parts, "\n\n")))
end
else
if label == "모든 주제" then
desc = "모든 언어에 대한 최상위 주제 분류입니다."
additional = "사전 항목을 직접 포함하지 않고 다른 분류만을 포함합니다. 하위 분류는 두 종류로 나뉩니다:\n\n" ..
"* 맨 처음에 나열된, 언어 코드가 없는 하위 분류들은 이 분류와 유사한 그룹 분류로, 일반적인 주제 영역을 다룹니다. 그 아래에 더 세분화된 주제 영역이 있습니다.\n" ..
"* \"ko:모든 주제\"와 같이 언어 코드가 앞에 붙는 하위 분류들은 이 분류와 같지만 특정 언어에 대한 최상위 분류입니다. 특히 " ..
"[[:분류:ko:모든 주제]]에서 한국어 관련 주제를 찾아보실 수 있습니다.\n" ..
"참고로 이 분류 체계 아래의 분류들은 문법적이 아닌 의미적으로 낱말을 분류합니다. " ..
"문법적 분류(예: 모든 프랑스어 동사)는 [[:분류:프랑스어 동사]]와 같이 언어 이름 전체를 사용하는 다른 명명 규칙을 가집니다."
return desc, additional
end
local has_umbrella_desc = topdata.umbrella and topdata.umbrella.description or topdata.umbrella_description
desc = function()
local desc = topdata.umbrella and get_and_cache(data, topdata.umbrella, "description") or
get_and_cache(data, topdata, "umbrella_description")
if not desc then
desc = get_and_cache(data, topdata, "description")
if desc then
desc = replace_special_descriptions(data, desc)
desc = remove_lang_params(desc)
desc = desc:gsub("%.$", "")
desc = "이 분류는 " .. desc .. " 주제와 관련이 있습니다."
end
end
if not desc then
desc = "다양한 특정 언어의 " .. label .. " 관련 분류입니다."
end
return postprocess_thesaurus(substitute_template_specs(data, desc))
end
preceding = topdata.umbrella and topdata.umbrella.preceding or not has_umbrella_desc and topdata.preceding
if preceding then
preceding = remove_lang_params(preceding)
end
additional = function()
local additional_parts = {}
local topdata_additional = topdata.umbrella and topdata.umbrella.additional or
not has_umbrella_desc and topdata.additional
if topdata_additional then
insert(additional_parts, remove_lang_params(topdata_additional))
end
insert(additional_parts, "{{{umbrella_msg}}}")
if not data.thesaurus_data then
insert(additional_parts, get_additional_msg(data))
local labels_msg = get_labels_categorizing(data)
if labels_msg then
insert(additional_parts, labels_msg)
end
end
return postprocess_thesaurus(substitute_template_specs(data, concat(additional_parts, "\n\n")))
end
end
preceding = substitute_template_specs(data, preceding)
return desc, additional, preceding
end
local function normalize_sort_key(data, sort)
local lang, label = data.lang, data.label
if not sort then
-- 정렬 키 기본값을 레이블로 할 때, 영어 관사 'The' 또는 'A'를 제거.
local stripped_sort = label:match("^[Tt]he (.*)$")
if stripped_sort then sort = stripped_sort end
if not stripped_sort then
stripped_sort = label:match("^[Aa] (.*)$")
if stripped_sort then sort = stripped_sort end
end
if not stripped_sort then sort = label end
end
sort = substitute_template_specs(data, sort)
if not lang then
sort = " " .. sort
end
return sort
end
local function get_topic_parents(data)
local topdata, lang, label = data.topdata, data.lang, data.label
local parents = topdata.parents
if not lang and label == "모든 주제" then
return {{ name = "분류:기본", sort = "주제" }}
end
if not parents or #parents == 0 then
return nil
end
local ret = {}
for _, parent in ipairs(parents) do
parent = mw.clone(parent)
if type(parent) ~= "table" then
parent = {name = parent}
end
parent.sort = normalize_sort_key(data, parent.sort)
if type(parent.name) ~= "string" then
error(("내부 오류: parent.name이 문자열이 아닙니다: parent = %s"):format(dump(parent)))
end
if parent.name:find("^분류:") or parent.nontopic then
-- 그대로 둠
parent.nontopic = nil
else
parent.name = make_category_name(lang, parent.name)
end
parent.name = substitute_template_specs(data, parent.name)
insert(ret, parent)
end
local function make_list_of_type_parent(typ_en)
local typ_ko
if typ_en == "related-to" then typ_ko = "관련"
elseif typ_en == "set" then typ_ko = "집합"
elseif typ_en == "type" then typ_ko = "유형"
elseif typ_en == "name" then typ_ko = "명칭"
elseif typ_en == "grouping" then typ_ko = "그룹"
else typ_ko = typ_en end
return {
name = make_category_name(lang, typ_ko .. " 분류 목록"),
sort = (not lang and " " or "") .. label,
}
end
if topdata.type ~= "toplevel" then
local types = split_types(topdata.type)
for _, typ in ipairs(types) do
insert(ret, make_list_of_type_parent(typ))
end
if #types > 1 then
insert(ret, make_list_of_type_parent("복합"))
end
end
-- 포괄 분류를 추가.
if lang then
insert(ret, {
name = make_category_name(nil, label),
sort = lang:getCanonicalName(),
})
end
return ret
end
local function get_thesaurus_parents(data)
local topdata, lang, label = data.topdata, data.lang, data.label
local parent_substitutions = data.thesaurus_data.parent_substitutions
local parents = topdata.parents
if not parents or #parents == 0 then
return nil
end
local ret = {}
for _, parent in ipairs(parents) do
-- Process parent categories as follows:
-- 1. skip non-topic cats and meta-categories that start with "List of"
-- 2. map "en:All topics" to "English thesaurus entries" (and same for other languages), but map "All topics" itself to the root "Thesaurus" category
-- 3. check if this parent is to be substituted, if so, substitute it
-- 4. prepend "Thesaurus:" to all other category names
parent = mw.clone(parent)
if type(parent) ~= "table" then
parent = {name = parent}
end
parent.sort = normalize_sort_key(data, parent.sort)
if type(parent.name) ~= "string" then
error(("내부 오류: parent.name이 문자열이 아닙니다: parent = %s"):format(dump(parent)))
end
if parent.name:find("^분류:") or parent.nontopic then
-- 건너뜀
elseif parent.name == "모든 주제" or parent_substitutions[parent.name] == "모든 주제" then
if not lang then
insert(ret, { name = "시소러스", sort = label })
else
insert(ret, { name = "시소러스 항목", sort = parent.sort, lang = lang:getCode(), is_label = true })
end
else
parent.name = "시소러스:" .. make_category_name(lang, parent_substitutions[parent.name] or parent.name)
parent.name = substitute_template_specs(data, parent.name)
insert(ret, parent)
end
end
-- 시소러스 전용 분류가 아니라면, 비-시소러스 버전의 분류를 상위 분류로 추가.
if not topdata.thesaurusonly then
insert(ret, { name = make_category_name(lang, label), sort = " " })
end
-- 포괄 분류를 추가.
if lang then
insert(ret, {
name = "시소러스:" .. make_category_name(nil, label),
sort = lang:getCanonicalName(),
})
end
return ret
end
local function generate_spec(category, lang, upcase_label, thesaurus_data)
local label_data = require(topic_data_module)
local label
-- Convert label to lowercase if possible
local lowercase_label = mw.getContentLanguage():lcfirst(upcase_label)
-- Check if the label exists
local labels = label_data["LABELS"]
if labels[lowercase_label] then
label = lowercase_label
else
label = upcase_label
end
local topdata = labels[label]
-- Go through handlers
if not topdata then
for _, handler in ipairs(label_data["HANDLERS"]) do
topdata = handler.handler(label)
if topdata then
topdata.module = handler.module
break
end
end
end
if not topdata then
return nil
end
local data = {
category = category,
lang = lang,
label = label,
topdata = topdata,
thesaurus_data = thesaurus_data,
}
local description, additional, preceding = get_description_additional_preceding(data)
local parents
if thesaurus_data then
parents = get_thesaurus_parents(data)
else
parents = get_topic_parents(data)
end
return {
lang = lang and lang:getCode() or nil,
description = description,
additional = additional,
preceding = preceding,
parents = parents,
breadcrumb = get_breadcrumb(data),
displaytitle = format_displaytitle(data, "include lang prefix", "upcase"),
topright = get_topright(data),
module = topdata.module,
can_be_empty = not lang,
hidden = false,
}
end
-- '시소러스:...' 분류를 위한 핸들러.
table.insert(raw_handlers, function(data)
local code, upcase_label = data.category:match("^시소러스:(%l[%a-]*%a):(.+)$")
local lang
if code then
lang = require(languages_module).getByCode(code)
if not lang then
mw.log( ("분류 '%s'는(은) 언어별 시소러스 분류처럼 보이지만 언어 접두사와 일치시킬 수 없습니다."):format(data.category) )
return nil
end
else
upcase_label = data.category:match("^시소러스:(.+)$")
end
if upcase_label then
local thesaurus_data = require(thesaurus_data_module)
if thesaurus_data.parent_substitutions[lcfirst(upcase_label)] then
error(("이 분류는 시소러스 분류로 허용되지 않습니다: %s (자세한 내용은 [[모듈:category tree/topic/thesaurus]]의 상위 분류 치환 목록 참조)")
:format(data.category))
end
return generate_spec(data.category, lang, upcase_label, thesaurus_data)
end
end)
-- 일반 주제 분류를 위한 핸들러.
table.insert(raw_handlers, function(data)
local code, upcase_label = data.category:match("^(%l[%a-]*%a):(.+)$")
local lang
if code then
lang = require(languages_module).getByCode(code)
if not lang then
mw.log( ("분류 '%s'는(은) 언어별 주제 분류처럼 보이지만 언어 접두사와 일치시킬 수 없습니다."):format(data.category) )
return nil
end
else
upcase_label = data.category
end
return generate_spec(data.category, lang, upcase_label)
end)
-----------------------------------------------------------------------------
-- --
-- 원시(RAW) 분류 --
-- --
-----------------------------------------------------------------------------
raw_categories["Thesaurus"] = {
description = "별도의 이름공간에 위치한 위키낱말사전 시소러스 항목들을 위한 분류입니다.",
additional = [=[시소러스를 탐색하는 방법에는 '''세 가지'''가 있습니다:
* '''[[:분류:언어별 시소러스 항목]]'''에서 시작하세요.
* 아래 검색 상자를 이용하세요.
* 아래 "하위 분류"의 링크를 사용하여 주제별로 시소러스를 탐색하세요.
주요 프로젝트 문서는 [[위키낱말사전:시소러스]]입니다.
{{ws header|<nowiki/>|link=}}]=],
parents = {
"분류:기본",
"분류:위키낱말사전 프로젝트",
},
}
return {RAW_CATEGORIES = raw_categories, RAW_HANDLERS = raw_handlers}