Модуль:hyphenation
Внешний вид
Модуль предназначен для расстановки знаков переноса в строке. Этот модуль используется в шаблоне {{перенос}}.
Описание функций и параметров
hyphenate
— функция форматирования строки в ссылки.- Принимает один два параметра, которые могут иметь значения:
text=
— исходная строка (обязательный)delimiter=
— символ переноса (необязательный, по умолчанию = "¦")
- Принимает один два параметра, которые могут иметь значения:
Технические детали
Для расстановки переноса используется алгоритм П. Христова в модификации Дымченко и Варсанофьева.
Длина символа переноса должна быть равна 1. Обрабатываются только русские и английские слова состоящие из символов латиницы и кириллицы и знака ударения (акут). Не допускается более одного знака ударения в слове. Символы пунктуации игнорируются.
Примеры
Код | Результат |
---|---|
{{#invoke:hyphenation|hyphenate|speak}} |
spe¦ak |
{{#invoke:hyphenation|hyphenate|говори́ть}} |
го¦во¦ри́ть |
{{#invoke:hyphenation|hyphenate|подытожить|-}} |
по-ды-то-жить |
{{перенос|вводи́ть в заблужде́ние}} |
вво¦ди́ть в заб¦луж¦де́¦ние |
{{#invoke:hyphenation|hyphenate|lead astray}} |
le¦ad ast¦ray |
local p = {}
--[[
hyphenate
Эта функция расставляет переносы по алгоритму П. Христова в модификации Дымченко и Варсанофьева.
Использование:
{{#invoke:hyphenation|hyphenate|текст|разделитель}}
или
{{#invoke:hyphenation|hyphenate|text=текст|delimiter=разделитель}}
]]
function p.hyphenate(frame)
-- разбор параметров
local function getParameters( frame_args, arg_list )
local new_args = {};
local index = 1;
local value;
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index];
index = index + 1;
end
new_args[arg] = value;
end
return new_args;
end
-- разделение строки
local function mygsplit(str, pattern)
local l = mw.ustring.len( str );
return function (state, s)
if s <= l then
local e, n = mw.ustring.find( str, pattern, s, false );
local ret;
local sep = '';
if not e then
ret = mw.ustring.sub( str, s );
s = l + 1
elseif n < e then
ret = mw.ustring.sub( str, s, e );
if e < l then
s = e + 1;
else
s = l + 1;
end
else
ret = e > s and mw.ustring.sub( str, s, e - 1 ) or '';
sep = mw.ustring.sub( str, e, n );
s = n + 1
end
return s, ret, sep
else
s = nil;
return s, ret, sep
end
end, nil, 1 -- iterator, state, initial value
end
-- растановка переносов в тексте
local function parse(text, sep)
local x = "йьъ"; -- специальная
local g = "аеёиоуыэюяaeiouy"; -- гласная
local s = "бвгджзклмнпрстфхцчшщbcdfghjklmnpqrstvwxz"; -- согласная
local rules = {
{ "xgg", 1 },
{ "xgs", 1 },
{ "xsg", 1 },
{ "xss", 1 },
{ "gssssg", 3 },
{ "gsssg", 3 },
{ "gsssg", 2 },
{ "sgsg", 2 },
{ "gssg", 2 },
{ "sggg", 2 },
{ "sggs", 2 }
};
local sb ='';
local ltext = mw.ustring.lower(text);
ltext = mw.ustring.gsub(ltext, mw.ustring.char(769), ''); -- убираем знаки ударени
-- заменяем символы в строке символами шаблона
for i=1, mw.ustring.len(ltext) do
local c = mw.ustring.sub( ltext, i, i);
if (mw.ustring.find(x, c, 1, true) ~= nil) then
sb = sb .. 'x';
elseif (mw.ustring.find(g, c, 1, true) ~= nil) then
sb = sb .. 'g';
elseif (mw.ustring.find(s, c, 1, true) ~= nil) then
sb = sb .. 's';
end
end
for i, ru in pairs(rules) do
local hp = ru[1]; -- шаблон
local pos = ru[2]; -- позиция
local index = mw.ustring.find(sb, hp, 1, true);
while index ~= nil do
local acutpos = mw.ustring.find( text, mw.ustring.char(769), 1, true); -- позиция знака ударения
local actualIndex = index + pos -1;
sb = mw.ustring.sub( sb, 1, actualIndex) .. sep .. mw.ustring.sub( sb, actualIndex+1);
-- mw.log('acutpos = ' .. tostring(acutpos) .. ', index=' .. tostring(actualIndex))
if acutpos ~= nil and acutpos-1 <= actualIndex then
actualIndex = actualIndex +1;
end
text = mw.ustring.sub( text, 1, actualIndex) .. sep .. mw.ustring.sub( text, actualIndex+1);
index = mw.ustring.find(sb, hp, 1, true);
end
end
return text;
end
local args = frame.args;
if args[1] == nil then
args = frame:getParent().args;
end
local new_args = getParameters( args, {'text', 'delimiter' } );
local text = new_args['text'] or '';
local delimiter = new_args['delimiter'] or '¦';
local pattern = '[%s%p]+';
local result = '';
for i, str, sep in mygsplit(text, pattern ) do
if str ~= '' then
result = result .. parse(str, delimiter);
end
if sep ~= '' then
result = result .. sep;
end
end
if result == '' then
return text;
else
return result;
end
end
return p;