Модул:stringconvert
Модуль предназначен для форматирования строки в ссылки. Этот модуль используется в шаблоне {{aslinks}}
.
Описание функций и параметров
[вироиш]aslinks
— функция форматирования строки в ссылки.- Принимает шесть параметров, которые могут иметь значения:
text=
— исходная строка (обязательный)delimiter=
— строка из разделителей (необязательный, по умолчанию = ", " — разделять слова запятой или пробелом)nospace=
— без пробела (yes или no).hide=
— слово, которые нужно удалить из текста (удаляются также ссылки на слово).nocomment
— без комментариев в круглых скобках (yes или no).lang=
— буквенный код языка (ru
,en
,fr
и т.п.).
- Принимает шесть параметров, которые могут иметь значения:
strip_macrons
— функция удаляет макроны, знаки ударения и заменяет слоговые знаки на обычные- Принимает один неименованный параметр — исходную строку для обработки.
Технические детали
[вироиш]Ссылки в результирующей строке будут разделены также, как и в исходной. Существующие ссылки сохраняются. Например:
{{#invoke:stringconvert|aslinks|петь орать голосить}}
→ петь орать голосить{{#invoke:stringconvert|aslinks|[[петь|пою]], орать, , голосить}}
→ пою, орать, , голосить
Для удаления слова или словосочетания из строки можно использовать параметр hide=
. Следующие за словом пробелы и запятая тоже удаляются. Например:
{{#invoke:stringconvert|aslinks|петь орать голосить|hide=петь}}
→ орать голосить{{#invoke:stringconvert|aslinks|поднять [[якорь|якоря]], полный вперед|hide=якорь}}
→ поднять полный вперед{{#invoke:stringconvert|aslinks|под вечер мы [[остановиться|остановились]]|hide=под вечер}}
→ под вечер мы остановились{{#invoke:stringconvert|aslinks|[[вечер]]ом мы [[остановиться|остановились]]|hide=вечер}}
→ мы остановились
С помощью второго параметра, можно переопределить разделители по умолчанию. Пробел в разделители добавлять не нужно, он добавляется по умолчанию. Например:
{{#invoke:stringconvert|aslinks|choix {{m}}; sélection {{f}}|,;}}
→ choix ҷинси мардона; sélection ҷинси занона
Если нужно подавить добавление пробела используйте параметр nospace=1
. Например:
{{#invoke:stringconvert|aslinks|говоря́т тебе, говорят вам||1}}
→ говоря́т тебе, говорят вам{{#invoke:stringconvert|aslinks|семь бед — один ответ; беда одна не ходит'', за собой другую водит''|nospace=1}}
→ семь бед — один ответ; беда одна не ходит, за собой другую водит{{#invoke:stringconvert|aslinks|семь бед — один ответ; беда одна не ходит'', за собой другую водит''|;|1}}
→ семь бед — один ответ; беда одна не ходит, за собой другую водит
Используйте в разделителе escape последовательность  
, если нужно разделять строки только пробелом. Например сравните:
{{#invoke:stringconvert|aslinks|несчастье, крайне [[тяжёлый|тяжёлое]] или [[неприятный|неприятное]] событие или обстоятельство}}
→ несчастье, крайне тяжёлое или неприятное событие или обстоятельство{{#invoke:stringconvert|aslinks|несчастье, крайне [[тяжёлый|тяжёлое]] или [[неприятный|неприятное]] событие или обстоятельство| }}
→ несчастье, крайне тяжёлое или неприятное событие или обстоятельство
Чтобы учесть все разделители и знаки препинания используйте строку %s%p
:
{{#invoke:stringconvert|aslinks|Non, je vous préviens que si vous ne me dites pas que nous avons la guerre, si vous vous permettez encore de pallier toutes les infamies, toutes les atrocités de cet Antichrist (ma parole, j'y crois) — je ne vous connais plus, vous n'êtes plus mon ami, vous n'êtes plus мой верный раб, comme vous dites.|%s%p|1}}
→ Non, je vous préviens que si vous ne me dites pas que nous avons la guerre, si vous vous permettez encore de pallier toutes les infamies, toutes les atrocités de cet Antichrist (ma parole, j'y crois) — je ne vous connais plus, vous n'êtes plus mon ami, vous n'êtes plus мой верный раб, comme vous dites.
Внешние и внутренние сылки, HTML теги, круглые, угловые скобки, одинарные парные кавычки, пайп, амперсант и одиночные знаки пунктуации — пропускаются. Например:
{{#invoke:stringconvert|aslinks|мн.: люди, грабли}}
→ мн.: люди, грабли{{#invoke:stringconvert|aslinks|''мн.'': люди, грабли}}
→ мн.: люди, грабли{{#invoke:stringconvert|aslinks|<i>мн.</i>: люди, грабли}}
→ мн.: люди, грабли{{#invoke:stringconvert|aslinks|{{мн}} люди, грабли}}
→ муғулӣ люди, грабли{{#invoke:stringconvert|aslinks|''частичн.'': добро, счастье, удача}}
→ частичн.: добро, счастье, удача{{#invoke:stringconvert|aslinks|grablje {{f}} {{мн.}}}}
→ grablje ҷинси занона Шаблон:мн.{{#invoke:stringconvert|aslinks|{{incorrect|ми́нутый}}}}
→ *ми́нутый{{#invoke:stringconvert|aslinks|{{пример|текст в примере}}}}
→ Шаблон:пример
Для формирование ссылки на языковый раздел используйте параметр lang
{{#invoke:stringconvert|aslinks|prōcēssus|lang=la}}
→ prōcēssus{{#invoke:stringconvert|aslinks|processus|lang=fr}}
→ processus
local p = {}
local ACUTE = mw.ustring.char(0x0301)
local MACRON = mw.ustring.char(0x0304)
local BREVE = mw.ustring.char(0x0306)
local DIAER = mw.ustring.char(0x0308)
local macron_tbl =
{
["ĀĂ"] = "A", ["āă"] = "a",
["ĒĔË"] = "E", ["ēĕë"] = "e",
["ĪĬÏ"] = "I", ["īĭï"] = "i",
["ŌŎ"] = "O", ["ōŏ"] = "o",
["ŪŬÜ"] = "U", ["ūŭü"] = "u",
["Ȳ"] = "Y", ["ȳ"] = "y",
[ACUTE .. MACRON .. BREVE .. DIAER] = ''
}
--[[
strip_macrons
Эта функция удаляет макроны, знаки ударения и заменяет слоговые знаки на обычные.
Использование:
{{#invoke:stringconvert|strip_macrons|текст}}
]]
function p.strip_macrons(str)
if type(str) == 'table' then -- проверка на глобальное использование
str = str.args[1]
end
for k, v in pairs( macron_tbl ) do
str = mw.ustring.gsub(str, "[" .. k .. "]", function(c)
return v
end)
end
return str;
end
--[[
aslink
Эта функция преобразует разделённый запятыми текст в разделённые запятыми викиссылки.
Встречающиеся знаки ударения сохраняются в тексте ссылки, но убираются из цели.
Использование:
{{#invoke:stringconvert|aslinks|текст|разделитель}}
или
{{#invoke:stringconvert|aslinks|text=текст|delimiter=разделитель|nospace=1|hide=слово|nocomment=1|lang=код языка}}
]]
function p.aslinks ( 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
-- определение булевого значения в параметре
function getBoolean( boolean_str )
local boolean_value = false;
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower();
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then
boolean_value = false;
else
boolean_value = true;
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str;
end
return boolean_value
end
local new_args = getParameters( frame.args, {'text', 'delimiter', 'nospace', 'hide', 'nocomment', 'lang' } );
local hide_word = new_args['hide'] or '';
local text = new_args['text'] or '';
local delimiter = new_args['delimiter'];
if delimiter == nil or delimiter == '' then
delimiter = ',';
else
delimiter = mw.text.decode(delimiter);
end
local nospace = getBoolean( new_args['nospace']);
if not nospace then
-- добавляем пробел и неразрывный пробел
delimiter = delimiter .. ' ' .. mw.ustring.char(160);
end
local nocomment = getBoolean( new_args['nocomment']);
if nocomment then
delimiter = delimiter .. '%(%)';
end
local lang= new_args['lang'];
local langlink = '';
if lang then
local trimmed = mw.text.trim(lang);
if trimmed == 'ru' then
langlink = "#Русский"
else
local languages = mw.loadData("Module:languages/data");
local l = languages[trimmed];
if l and l[2] then
langlink = '#' .. l[2];
end
end
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 findtag( str, s )
local ct = 1;
local start_pos = 1;
local start_tag = '';
while true do
local e, n, close_tag, tag_name, single_tag = mw.ustring.find( str, "<(/?)([A-Za-z]+).-(/?)>", s, false );
if not e then
return nil, -1
else
if single_tag ~= '' then
if start_tag == '' then
return e, n; -- найден одиночный непарный тэг
else
s = n + 1; -- пропускаем вложенный непартный тэг
end
elseif close_tag ~= '' then
if start_tag == '' then
return e, n; -- найден одиночный закрывающий тэг
elseif tag_name == start_tag then
ct = ct - 1;
if ct == 1 then
return start_pos, n; -- найден закрывающий тэг
else
s = n + 1; -- найден вложенный закрывающий тэг
end
else
s = n + 1; -- пропускаем вложенный закрывающий тэг
end
else
if start_tag == '' then
start_tag = tag_name;
start_pos = e;
ct = ct + 1;
s = n + 1; -- найден первый открывающий тэг
elseif tag_name == start_tag then
ct = ct + 1;
s = n + 1; -- найден вложенный открывающий тэг с тем же именем
else
s = n + 1; -- пропускаем вложенный открывающий тэг
end
end
end
end
end
-- разделение тэгов
local function tsplit(str)
local l = mw.ustring.len( str );
return function (state, s)
if s <= l then
local e, n = findtag( str, s );
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 myparser(text, level)
if text ~= '' then
if mw.ustring.find(text, '[|&]', 1, false) ~= nil or -- не обрабатываем текст, содержащий пайп и апмерсант
mw.ustring.find(text, '^[%p%d]+$', 1, false) ~= nil then -- и одиночные знаки пунктуации и цифры
return text;
else
local before, str, after = mw.ustring.match(text, "^(%s*)(.-)(%s*)$", 1);
if before ~= nil and str ~= nil and str ~= '' then
local link = str;
if lang == "la" then
link = p.strip_macrons(str) -- убираем диакритические знаки
else
link = mw.ustring.gsub(str, ACUTE, '') -- убираем только знак ударения
end
if str ~= link or langlink ~= '' then
str = link .. langlink .. '|'.. str;
end
text = before .. "[[" .. str .. "]]" .. after;
end
end
end
return text;
end
local handlers = {};
-- разделение текста по шаблону
local function parse(text, level)
local result = "";
local pattern = handlers[level][1];
local parser = handlers[level][2];
for i, str, sep in mygsplit(text, pattern, false ) do
if str ~= "" then
result = result .. parser(str, level+1);
end
if sep ~= "" then
result = result .. sep;
end
end
if result == "" then
return text;
else
return result;
end
end
local stripers = {};
local striped = {};
local stripid = 0;
local k = 1;
-- замена текста с сохранением
local function striptext(text)
stripid = stripid +1;
local key = '<' .. stripid .. '>';
striped[key] = text;
return key;
end
-- вырезание текста по шаблону
local function strip(text)
for j, pattern in ipairs(stripers) do
local result = "";
for i, str, sep in mygsplit(text, pattern, false ) do
if str ~= "" then
result = result .. str;
end
if sep ~= "" then
result = result .. striptext(sep);
end
end
if result ~= '' then
text = result; -- текст для следующего обработчика
end;
end
return text;
end
-- восстановление вырезанного текста по шаблону
local function unstrip(text)
local result = '';
for i, str, sep in mygsplit(text, "<%d->", false ) do
if str ~= "" then
result = result .. str;
end
if sep ~= "" then
result = result .. unstrip(striped[sep]);
end
end
return result;
end
-- вырезание тэгов
local function striptags(text)
local result = "";
for i, str, sep in tsplit(text) do
if str ~= "" then
result = result .. str;
end
if sep ~= "" then
result = result .. striptext(sep);
end
end
if result == '' then
return text;
else
return result;
end
end
-- обратная совестимость с шаблоном lang, куда иногда передается текст сразделенный шаблоном {{!}}
text = mw.ustring.gsub(text, '^%s*([^%[|,;]+|[^%]|,;]+)%s*$', '[[%1]]');
text = striptags(text); -- вырезаем HTML тэги
stripers = {}
table.insert(stripers, "{|.*|}"); -- исключаем таблицы
if not nocomment then
table.insert(stripers, "%b()"); -- исключаем текст в круглых скобках
end
table.insert(stripers, "%[%[.-%]%]%S*"); -- исключаем внутренние ссылки
table.insert(stripers, "%b[]"); -- исключаем внешние ссылки
table.insert(stripers, "'''[^']-'''"); -- исключаем текст в тройных одинарных кавычках
table.insert(stripers, "''[^']-''"); -- исключаем текст в двойных одинарных кавычках
text = strip(text); -- вырезаем по шаблону
local l = 1;
handlers[l] = { "\r?\n", parse }; l=l+1; -- исключаем разделители строк
handlers[l] = { "%b<>", parse }; l=l+1; -- исключаем текст в угловых скобках
handlers[l] = { "%s*[" .. delimiter .."]+%s*", myparser }; -- разделяем оставшееся
text = parse(text, 1); -- обрабатываем
if stripid ~= 0 then
text = unstrip(text); -- восстанавливаем вырезанное
end;
if hide_word ~= '' then
local cnt = 0;
-- удаление ссылки на слово
hide_word = mw.ustring.gsub( hide_word, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); -- маскируем спецсимволы
text, cnt = mw.ustring.gsub( text, '%[%[' .. hide_word ..'%|[^%]]*%]%]%w* *,? *', '' );
if cnt == 0 then
text, cnt = mw.ustring.gsub( text, '%[%[' .. hide_word ..'%]%]%w* *,? *', '' );
end
if cnt ~= 0 then
text = mw.ustring.gsub( text, '^%p+$', '' ); -- удаляем строку состоящую только из разделительных знаков
text = mw.ustring.gsub( text, '[,;] *;', ';' ); -- удаляем запятую перед точкой с запятой
text = mw.ustring.gsub( text, ', *$', '' ); -- удаляем запятую в конце строки
text = mw.ustring.gsub( text, '^[;,] *', '' ); -- удаляем запятую или точку с запятой в начале строки
end
end
return text;
end
return p