Обсуждение модуля:Морфо
-- Модуль:морфо v1.2 -- 2016-04-19
local export = {} local u = require("Module:utils") local wu = require("Module:wiki-utils")
-- TODO: трансфиксы в арабском, и инфиксы в латыни // отменяется? -- TODO: источники вынести в data-модуль // переносится на потом
local data = {} local title local morphemes = {} local reference = local categories = local category_replacements = {} local skip_categories = false
local DEBUG_CATEGORIES = false
local singular = { root = 'корень', prefixoid = 'префиксоид', prefix = 'приставка', suffix = 'суффикс', postfix = 'постфикс', suffixsoid = 'суффиксоид', interfix = 'интерфикс', ending = 'окончание', verb_ending = 'глагольное окончание', } local plural = { prefixoid = 'префиксоиды', prefix = 'приставки', suffix = 'суффиксы', postfix = 'постфиксы', suffixsoid = 'суффиксоиды', interfix = 'интерфиксы', ending = 'окончания', verb_ending = 'глагольное окончания', } local plural_key = { prefixoid = 'prefixoids', prefix = 'prefixes', suffix = 'suffixes', postfix = 'postfixes', suffixsoid = 'suffixsoids', interfix = 'interfixes', ending = 'endings', verb_ending = 'verb_endings', } local instrumental = { prefixoid = 'префиксоидом', prefix = 'приставкой', suffix = 'суффиксом', postfix = 'постфиксом', suffixsoid = 'суффиксоидом', interfix = 'интерфиксом', } local notation = { root = 'R', prefixoid = 'R', prefix = 'pr', suffix = 's', postfix = 'pt', suffixsoid = 'R', interfix = 'i', ending = 'f', verb_ending = 'f', }
-- Утилитная функция для формирования wiki-кода для категории function set_category(name) return ' ' end
function add_morpheme(m_type, m_value) table.insert(morphemes, {m_type=m_type, m_value=m_value}) end
function add_category(name) categories = categories .. set_category(name) if DEBUG_CATEGORIES then categories = categories .. wu.span_silver(' [Категория:' .. name .. ']') end end
function process_data() for m_type, items in pairs(data['category_replacements']) do category_replacements[m_type] = {} for _, values in pairs(items) do if type(values) == 'table' then category_replacements[m_type][values[1]] = values[2] end end end end
function parse_morphemes(args) for key, value in pairs(args) do cleared_value = mw.ustring.gsub(value, '[()]', ) if type(key) == 'number' then if mw.ustring.match(value, "^%-%-") ~= nil then value = mw.ustring.sub(value, 2) add_morpheme('suffixsoid', value) elseif mw.ustring.match(value, "%-%-$") ~= nil then value = mw.ustring.sub(value, 1, -2) add_morpheme('prefixoid', value) elseif mw.ustring.match(value, "^%-.*%-$") ~= nil then add_morpheme('interfix', value) elseif mw.ustring.match(value, "%-$") ~= nil then value = mw.ustring.sub(value, 1, -2) add_morpheme('prefix', value..'-') elseif mw.ustring.match(value, "^%-") ~= nil then if u.contains(data['known_morphemes']['postfixes'], cleared_value) then add_morpheme('postfix', value) else add_morpheme('suffix', value) end elseif mw.ustring.match(value, "^%+") ~= nil then fix_value = '-'..mw.ustring.sub(value, 2) if u.contains(data['known_morphemes']['verb_endings'], cleared_value) then add_morpheme('verb_ending', fix_value) else add_morpheme('ending', fix_value) end elseif value ~= then add_morpheme('root', '-'..value..'-') end else if key == 'и' then if value == 'т' then reference = 'по Тихонову' elseif value == 'т2' or value == 'т-ся' then if u.endswith(title, 'ся') then reference = '.. mw.ustring.sub(title, 1, -3) .. '(ся) по Тихонову' else reference = 'по Тихонову' end elseif value == 'т-сь' then if u.endswith(title, 'сь') then reference = '.. mw.ustring.sub(title, 1, -3) .. '(сь) по Тихонову' else reference = 'по Тихонову' end elseif u.startswith(value, 'т:') then reference = '.. mw.ustring.sub(value, 3) .. ' по Тихонову' elseif u.contains({'т3'}, value) then reference = 'Шаблон:Тихонов-3' elseif u.contains({'е'}, value) then reference = 'Шаблон:Ефремова' skip_categories = true elseif u.contains({'к', 'ке', 'к,е', 'к, е'}, value) then reference = '[Кузнецова и Ефремова]' skip_categories = true else -- reference = wu.span_red('(неизвестный источник)') reference = end end end end end
function prepare_output() if #morphemes == 0 then return "Корень: --." .. set_category('Нет сведений о составе слова/ru') end local items = {} local structure = {} local has_root = false local unknown_affix = false local wrong_characters = false local check_title = for i, morpheme in pairs(morphemes) do local m_type = morpheme['m_type'] -- тип морфемы local m_value = morpheme['m_value'] -- преобразованное значение для отображения local m_cat_value = mw.ustring.lower(mw.ustring.gsub(m_value, '[()]', )) -- убираем скобки для категории, а также нижний регистр if mw.ustring.match(mw.ustring.lower(m_value), '^[-+а-яёj∅’()]*$') == nil and mw.ustring.match(m_value, '^-[A-Za-z]*-$') == nil then wrong_characters = true end local check_morpheme = mw.ustring.gsub(m_value, '[-+j∅]', ) check_morpheme = mw.ustring.gsub(check_morpheme, '%(.+%)', ) check_title = check_title .. check_morpheme local m_title = singular[m_type] if u.contains({'prefix', 'prefixoid', 'suffix', 'suffixoid', 'postfix', 'interfix'}, m_type) then if category_replacements[m_type] and category_replacements[m_type][m_cat_value] then m_cat_value = category_replacements[m_type][m_cat_value] end end -- local m_cat_value = mw.ustring.gsub(m_value, '%/.*', ) -- m_value = mw.ustring.gsub(m_value, '%/', '|') table.insert(structure, notation[m_type]) if u.contains({'prefixoid', 'prefix', 'suffix', 'postfix', 'interfix', 'suffixsoid'}, m_type) then if m_type ~= 'interfix' and not skip_categories then add_category('Русские слова с ' .. instrumental[m_type] .. ' ' .. m_cat_value) -- категоризация по типам морфем m_value = '' .. m_value .. '' -- добавление ссылки для морфемы end if i > 1 and morphemes[i-1]['m_type'] == m_type then m_title = -- пропуск заголовка, если предыдущая морфема была того же типа elseif i < #morphemes and morphemes[i+1]['m_type'] == m_type then m_title = plural[m_type] -- использование множественного числа, если несколько подряд морфем одного типа end end if u.contains({'prefixoid', 'prefix', 'suffix', 'postfix', 'interfix', 'ending'}, m_type) and not skip_categories then key = plural_key[m_type] value = m_cat_value if m_type == 'ending' then value = mw.ustring.gsub(m_cat_value, '^%-', '+') elseif m_type == 'prefixoid' then value = mw.ustring.gsub(m_cat_value, '%-$', '--') end if not u.contains(data['known_morphemes'][key], value) then unknown_affix = true -- категоризация неизвестных морфем m_value = m_value .. wu.span_red("?") -- добавление красного вопросика end end if m_type == 'root' then has_root = true end if m_title ~= then item = m_title .. ': ' .. "" .. m_value .. ";" table.insert(items, item) else if m_type == 'interfix' and mw.ustring.sub(items[#items], -5, -5) ~= '>' then items[#items] = mw.ustring.sub(items[#items], 1, -6) .. m_value .. ";" else items[#items] = mw.ustring.sub(items[#items], 1, -5) .. m_value .. ";" end end end if not skip_categories then add_category('Русские слова, тип морфемного строения ' .. table.concat(structure, '-')) if unknown_affix then add_category('Ошибка в морфемном разборе (неизвестный аффикс)/ru') end end if not has_root then add_category('Ошибка в морфемном разборе (нет корня)/ru') end if wrong_characters then add_category('Ошибка в морфемном разборе (недопустимые символы)/ru') end local title_without_hyphens = mw.ustring.gsub(title, '[-]', ) -- mw.log('"' .. title_without_hyphens .. '"') -- mw.log('"' .. check_title .. '"') if check_title ~= title_without_hyphens then if mw.ustring.lower(check_title) ~= mw.ustring.lower(title_without_hyphens) then add_category('Ошибка в морфемном разборе (не соответствует исходному слову)/ru') else categories = categories .. ' ' --add_category('Ошибка в морфемном разборе (не соответствует регистру исходного слова)/ru') end end local output = table.concat(items, ' ') local result = mw.ustring.sub(u.capfirst(output), 1, -2) if reference ~= then result = result .. ' ' .. reference end result = result .. '.' .. categories return result end
function generate_docs() result = for i, m_type in pairs({'prefix', 'prefixoid', 'interfix', 'suffix', 'suffixsoid', 'ending', 'verb_ending', 'postfix'}) do result = result .. "===" .. u.capfirst(plural[m_type]) .. "===" .. '\n'
result = result .. "
values = data['known_morphemes'][plural_key[m_type]] empty = true for i, value in pairs(values) do empty = false value = mw.ustring.gsub(value, '%-%-', '-') value = mw.ustring.gsub(value, '%+', '-') if u.contains({'prefixoid', 'prefix', 'suffix', 'postfix', 'suffixsoid'}, m_type) then cat_name = 'Русские слова с ' .. instrumental[m_type] .. ' ' .. value result = result .. "# " .. value .. "" .. ' (кат)\n" -- 0 else result = result .. "# " .. value .. "\n" end end
result = result .. "\n"
if empty then result = result .. "# Пусто\n" end end return result end
-- Главная функция, которая вызывается в модуле. function export.get(frame) local lang = frame.args['язык'] local args = u.clone(frame:getParent().args) title = u.get_base() data = mw.loadData("Module:морфо/data/" .. lang); process_data() parse_morphemes(args) return frame:preprocess(prepare_output()) end
-- Функция, для генерации документации дата-модуля. function export.docs(frame) local lang = frame.args['язык'] data = mw.loadData("Module:морфо/data/" .. lang); return frame:preprocess(generate_docs()) end
return export