Модуль:Tools: различия между версиями

Материал из Кадровый состав НКВД 1935-1939
Перейти к навигации Перейти к поиску
Нет описания правки
Нет описания правки
(не показаны 23 промежуточные версии этого же участника)
Строка 1: Строка 1:
local tools = {}
local tools = {}


function tools.errorMsg( tpt, errorTxt, errorAdvice )
----------------------------------------------------------------------- |errorMsg|
if errorAdvice then
local function enumeratePara( para )
errorAdvice = '<span class="nkvd-error-advice">' .. errorAdvice .. '. </span>'
else
errorAdvice = ''
end
return '<div class="nkvd-error"><span class="nkvd-error-tpt">{{ '
.. '[[Шаблон:' .. tpt .. '|' .. tpt .. ']]' -- вместо .. Frame:getParent():getTitle()
.. tools.enumeratePara( mw.getCurrentFrame():getParent().args )
.. ' }}</span><span class="nkvd-error-diag">'
.. errorTxt .. '. </span>' .. errorAdvice .. '</div>'
.. '[[Категория:Страницы с ошибками вызова шаблона «' .. tpt  .. '»]]'
end
 
function tools.enumeratePara( para )
local res = ''
local res = ''
local maxi = 0
local maxi = 0
Строка 30: Строка 17:
end
end


 
function tools.errorMsg( tpt, errorTxt, errorAdvice )
function tools.flip( array, value )
if errorAdvice then
    local res = {}
errorAdvice = '<span class="nkvd-error-advice">' .. errorAdvice .. '. </span>'
    for k, v in pairs( array ) do
else
        res[v] = value or k
errorAdvice = ''
    end
    return res
end
 
function tools.args( args )
local res, x = {}
for k,v in pairs( args ) do
x = mw.text.trim(v)
if x ~= '' then
res[k] = x
end
end
end
if x then
return '<div class="nkvd-error"><span class="nkvd-error-tpt">{{ '
res['___HAS_ARG___'] = true
.. '[[Шаблон:' .. tpt .. '|' .. tpt .. ']]' -- вместо .. Frame:getParent():getTitle()
end
.. enumeratePara( mw.getCurrentFrame():getParent().args )
return res
.. ' }}</span><span class="nkvd-error-diag">'
.. errorTxt .. '. </span>' .. errorAdvice .. '</div>'
.. '[[Категория:Страницы с ошибками вызова шаблона «' .. tpt  .. '»]]'
end
end


---------------------------------------------------------------------- |checkargs|
function tools.checkargs( args, names )
function tools.checkargs( args, names )
     local res = {}
     local res = {}
Строка 79: Строка 58:
end
end


---------------------------------------------------------------------- |parseDate|
function tools.parseDate( indate, border )
function tools.parseDate( indate, border )
border = border or 1880
border = border or 1880
Строка 128: Строка 108:
return nil
return nil
end
end
--@TODO Не хватает честной проверки числа в зависимости от месяца
--TODO: Не хватает честной проверки числа в зависимости от месяца
return table.concat( { y, m, d }, '-' ), y, m, d
return table.concat( { y, m, d }, '-' ), y, m, d
end
end


-------------------------------------------------------------------- |reparseDate|
function tools.reparseDate( value )
function tools.reparseDate( value )
if #value == 10 then
if #value == 10 then
Строка 147: Строка 128:
end
end


----------------------------------------------------------------------- |textDate|
local mes = {
local mes = {
i = { 'январь', 'февраль',  'март',  'апрель',  'май',  'июнь',  'июль',  'август',  'сентябрь',  'октябрь',  'ноябрь',  'декабрь', 'год'  },
i = { 'январь', 'февраль',  'март',  'апрель',  'май',  'июнь',  'июль',  'август',  'сентябрь',  'октябрь',  'ноябрь',  'декабрь', 'год'  },
Строка 167: Строка 149:
end
end


 
------------------------------------------------------------------------- |phrase|
function tools.phrase (text)
function tools.phrase (text)
text = mw.text.trim( text )
text = mw.text.trim( text )
Строка 181: Строка 163:
end
end


----------------------------------------------------------------------- |noPhrase|
function tools.noPhrase (text)
function tools.noPhrase (text)
text = mw.text.trim( text )
text = mw.text.trim( text )
Строка 190: Строка 173:
end
end


----------------------------------------------------------------------------- |db|
function tools.db( base, elem, field )
function tools.db( base, elem, field )
local el = base[elem]
local el = base[elem]
Строка 204: Строка 188:
end
end


 
------------------------------------------------------------------- |commonParams|
 
tools.dateLength = {[''] = 10, ['1'] = 10, ['2'] = 7, ['3'] = 4}
function tools.ReparseDate ( frame )
return tools.reparseDate(
string.sub(frame.args[1], 1, tools.dateLength[frame.args[2] or ''] ) )
end
 
 
 
 
function tools.commonParams( addendum, reference, source )
function tools.commonParams( addendum, reference, source )
if ( addendum or '' ) ~= '' then
if ( addendum or '' ) ~= '' then
Строка 222: Строка 196:
addendum = ''
addendum = ''
end
end
local refTools = require( 'Module:RefTools' )
if ( reference or '' ) ~= '' or ( source or '' ) ~= '' then
 
local refTools = require( 'Module:RefTools' )
reference = refTools.makeRef( reference )
reference = refTools.makeRef( reference )
source = refTools.makeRef( tools.formatIfUrl( 'what', source ), true )
source = refTools.makeRef( tools.formatIfUrl( 'what', source ), true )
else
reference = ''
source = ''
end
return addendum .. reference .. source
return addendum .. reference .. source
end
end


function tools.cq( tables, fields, args )
-------------------------------------------------------------------- |formatIfUrl|
return mw.ext.cargo.query( tables, fields, args )
function tools.formatIfUrl( whatwherefrom, txt )
if not txt then
return
end
if string.sub( txt, 1, 7 ) ~= 'http://'
and string.sub( txt, 1, 8 ) ~= 'https://'
and string.sub( txt, 1, 2 ) ~= '//' then
return txt, true
end
if string.find( txt, ' ' ) then
return txt, true
end
return require( 'Модуль:Сайт' ).link( whatwherefrom, txt )
end
end


------------------------------------------------------------------------ |segment|
function tools.segment( s )
function tools.segment( s )
if ( s or '' ) ~= '' then
if ( s or '' ) ~= '' then
return '<i>[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = 'segment', value = s } ) ) .. ' ' .. s .. ']</i>'
return '<i>[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = 'segment', value = s } ) )
.. ' ' .. s .. ']</i>'
end
end
end
end


--------------------------------------------------------------------------- |name|
function tools.name( name, idx )
function tools.name( name, idx )
local root
local root
Строка 257: Строка 250:
end
end


---------------------------------------------------------------------- |splitName|
function tools.splitName( Name, redlink )
function tools.splitName( Name, redlink )
local name = Name
local name = Name
local l, f, m, d
local l, f, m, d
local warn = {} -- мягкие предупреждения начинаются с пробела
local warn = {} -- мягкие предупреждения начинаются с пробела
if string.find( name, '  ', 1, true ) then  
if string.find( name, '  ', 1, true ) then
warn[#warn+1] = 'В имени персоны нельзя ставить несколько пробелов подряд'
warn[#warn+1] = 'В имени персоны нельзя ставить несколько пробелов подряд'
name = string.gsub( name, '  +', ' ' )
name = string.gsub( name, '  +', ' ' )
Строка 270: Строка 264:
warn[#warn+1] = 'После запятой, точки и многоточия пробелы обязательны'
warn[#warn+1] = 'После запятой, точки и многоточия пробелы обязательны'
name = string.gsub( name, '([,#%.])([^ ])', '%1 %2' )
name = string.gsub( name, '([,#%.])([^ ])', '%1 %2' )
end
end
 
local tmp = string.find( name, ' (', 1, true )
local tmp = string.find( name, ' (', 1, true )
if tmp then
if tmp then
Строка 294: Строка 288:
if mw.ustring.match( f, '[а-я][а-я]%.$' ) then
if mw.ustring.match( f, '[а-я][а-я]%.$' ) then
warn[#warn+1] = 'Вместо точки после ФИО используйте шаблон «персона?»'
warn[#warn+1] = 'Вместо точки после ФИО используйте шаблон «персона?»'
end
end
f = string.gsub( f, '[#%.]', '' )
f = string.gsub( f, '[#%.]', '' )
if f ~= '' then
if f ~= '' then
tmp = string.find( f, ' ', 1, true )
tmp = string.find( f, ' ', 1, true )
if tmp then  
if tmp then
f, m = string.sub( f, 1, tmp-1), string.sub( f, tmp+1, -1 )
f, m = string.sub( f, 1, tmp-1), string.sub( f, tmp+1, -1 )
end
end
Строка 326: Строка 320:
end
end
if tmp ~= Name and #warn == 0 then
if tmp ~= Name and #warn == 0 then
warn[#warn+1] = ' Эталонная форма записи этого имени — «' .. tmp  
warn[#warn+1] = ' Эталонная форма записи этого имени — «' .. tmp
.. '». Вы уверены, что написали правильно?'
.. '». Вы уверены, что написали правильно?'
end
end


return  l, f, m, d, warn, name
return  l, f, m, d, warn, name
end
end


-------------------------------------------------------------------- |cargoString|
function tools.cargoString( s )
function tools.cargoString( s )
if ( s or '' ) == '' then
if ( s or '' ) == '' then
Строка 338: Строка 333:
end
end
return '="' .. s .. '"'
return '="' .. s .. '"'
end
function tools.formatIfUrl( whatwherefrom, txt )
if not txt then
return
end
if string.sub( txt, 1, 7 ) ~= 'http://'
and string.sub( txt, 1, 8 ) ~= 'https://'
and string.sub( txt, 1, 2 ) ~= '//' then
return txt, true
end
if string.find( txt, ' ' ) then
return txt, true
end
return require( 'Модуль:Сайт' ).link( whatwherefrom, txt )
end
end


 
--------------------------------------------------------------------- |podvigLink|
function tools.podvigLink( str )
function tools.podvigLink( str, imagesBase )
if not (str and tonumber( string.sub( str, 1, 1 ) ) ) then
if (str or '') == '' or string.sub(str, 1, 1) == '[' then
return str
return str
end
end
local pods = mw.text.split( str, '["%t%r%n%f ]*,["%t%r%n%f ]*' )
local pods = mw.text.split( str, '[%s]*,[%s]*' )
local tabtext = {
local tabtext = {
['+'] = {2, ', имеется наградной лист', },
['+'] = {2, ', имеется наградной лист', },
Строка 370: Строка 350:
local images = mw.site.server .. '/images'
local images = mw.site.server .. '/images'
local imagesP = mw.site.server .. '/images/obdmo/saved'
local imagesP = mw.site.server .. '/images/obdmo/saved'
local imagesB = 'http://localhome.raczynski.ru/tools/podvig/scan.php?k=1*4&l='
 
local res = {}
local res = {}
local x, y, tmp
local x, y, tmp, ico
local linkStyle, linkFull -- Style - 2/1/0 - картотека/представление/награждение, full - 0/1 - пустой/красим
local linkStyle, linkFull -- Style - 2/1/0 - картотека/представление/награждение, full - 0/1 - пустой/красим
for _, podvig in ipairs( pods ) do
for _, podvig in ipairs( pods ) do
if string.sub( podvig, 1, 1 ) == '/' then
if podvig == '' then
x = mw.text.split( podvig, '["%t%r%n%f ]+' )
elseif string.sub( podvig, 1, 1 ) == '/' then
y = {}
x = string.gsub( podvig, '%s+', ' ' )
if #x < 2 then
res[#res+1] = '<span class=image-store data-image="' .. x .. '"></span>'
res[#res+1] = '<i class="error fa fa-question"></i>'
-- x = mw.text.split( podvig, '[%s]+' )
else
-- y = {}
for i = 2, #x do
-- if #x < 2 then
if string.sub( x[i], -1, -1 ) == '-' then
-- res[#res+1] = '<i class="error fa fa-question"></i>'
tmp = string.sub( '00000000' .. string.sub( x[i], 1, -2 ), -8, -1 ) .. '_1'
-- else
else
-- for i = 2, #x do
tmp = string.sub( '00000000'..x[i], -8, -1 )
-- if imagesBase then
end
-- tmp = imagesB .. x[1] .. '&n=' .. x[i]
y[#y+1] =  '[' .. imagesP .. x[1] .. tmp .. '.jpg <i class="fa fa-file-text-o"  style="font-size:82%;" title="Сохраненные материалы"></i>]'  
-- ico = ''
end
-- else
res[#res+1] = '<span class=nkvd-hide-inline> ' .. table.concat( y, ' ' ) .. '</span>'
-- if string.sub( x[i], -1, -1 ) == '-' then
end
-- tmp = string.sub( '00000000' .. string.sub( x[i], 1, -2 ), -8, -1 ) .. '_1'
-- ico = '-o'
-- else
-- tmp = string.sub( '00000000'..x[i], -8, -1 )
-- ico = ''
-- end
-- tmp = imagesP .. x[1] .. '/' .. tmp .. '.jpg'
-- end
-- y[#y+1] =  '[' .. tmp
-- .. ' <i class="fa fa-file-text' .. ico
-- .. '"  style="color:gray; font-size:82%;" title="Сохраненные материалы"></i>]'
-- end
-- res[#res+1] = '<span class=nkvd-hide-inline> ' .. table.concat( y, ' ' ) .. '</span>'
-- end
else
else
x, y = string.match( podvig, '^(%d+) *([%+%-%*%%/#]*)$' )
x, y = string.match( podvig, '^(%d+) *([%+%-%*%%/#!]*)$' )
if not x then
if not x then
linkStyle = -1
linkStyle = -1
Строка 398: Строка 392:
if y == '#' then
if y == '#' then
linkStyle, linkFull = 2, 0
linkStyle, linkFull = 2, 0
y = ' представлена только в картотеке награждений'
y = ' в картотеке награждений'
elseif y == '!' then
linkStyle, linkFull = 3, 0
y = ''
else
else
linkFull, linkStyle = string.gsub( y, '%*', '' )
linkFull, linkStyle = string.gsub( y, '%*', '' )
Строка 408: Строка 405:
y = y[2]
y = y[2]
end
end
end
end
end
end
if linkStyle == -1 then
if linkStyle == -1 then
res[#res+1] = '<i class="error fa fa-question"></i>'
res[#res+1] = '<i class="error fa fa-question"></i>'
else
else
if linkFull == 0 then
if linkFull == 0 then
Строка 424: Строка 421:
if linkStyle == 0 then
if linkStyle == 0 then
tmp = 'nagrazhdenie'
tmp = 'nagrazhdenie'
elseif linkStyle == 3 then
tmp = 'yubileinaya_kartoteka'
else
else
tmp = 'predstavlenie'
tmp = 'predstavlenie'
end
end
res[#res+1] = ' &nbsp;[https://pamyat-naroda.ru/heroes/podvig-chelovek_' .. tmp  
res[#res+1] = ' &nbsp;[https://pamyat-naroda.ru/heroes/podvig-chelovek_' .. tmp
.. x .. ' <i class="fa fa-star' .. linkFull  
.. x .. '/ <i class="fa fa-star' .. linkFull
.. '" style="color:#D33738; font-size:82%;" title="Информация о награждении на сайте «Память народа»'  
.. '" style="color:#D33738; font-size:82%;" title="Информация о награждении на сайте «Память народа»'
.. y ..'"></i>] '
.. y ..'"></i>] '
.. '[http://podvignaroda.ru/#?id='  
.. '[http://podvignaroda.ru/#?id='
.. x .. ' <i class="fa fa-star' .. linkFull  
.. x .. ' <i class="fa fa-star' .. linkFull
.. '" style="color:gray; font-size:82%;" title="Информация о награждении на сайте «Подвиг народа»'  
.. '" style="color:gray; font-size:82%;" title="Информация о награждении на сайте «Подвиг народа»'
.. y ..'"></i>]'
.. y ..'"></i>]'
linkStyle = false
.. ' <span class=local-id data-id="' .. x .. '"></span>'
-- .. '<span class=nkvd-hide-inline> [http://localhome.raczynski.ru/tools/podvig?n=' .. x
-- .. ' <span style="color:#ffdd75" title="Sorry, internal use only">&nabla;</span>]</span>'
 
-- linkStyle = false
else
else
res[#res+1] = ' &nbsp;[http://podvignaroda.ru/#?id='  
res[#res+1] = ' &nbsp;[http://podvignaroda.ru/#?id='
.. x .. '  <i class="fa fa-folder-o'
.. x .. '  <i class="fa fa-folder-o'
.. '" style="color:gray; font-size:82%;" title="Информация о награждении на сайте «Подвиг народа»'  
.. '" style="color:gray; font-size:82%;" title="Информация о награждении на сайте «Подвиг народа»'
.. y ..'"></i>]'
.. y ..'"></i>]'
linkStyle = true
.. ' <span class=local-id data-id="' .. x .. '"></span>'
-- .. '<span class=nkvd-hide-inline> [http://localhome.raczynski.ru/tools/podvig?n=' .. x
-- .. ' <span style="color:#ffdd75" title="Sorry, internal use only">&nabla;</span>]</span>'
 
-- linkStyle = true
end
end
-- if grab then
-- res[#res] = res[#res] .. ' [' .. mw.site.server .. '/' .. mw.ext.luaglobal.get( 'GrabbingDir' ) .. '/' .. grab .. '<i class="fa fa-file-text-o"  style="font-size:82%;" title="Сохраненные материалы"></i>]'
-- end
end
end
end
end
end
end
 
return table.concat( res, ' &nbsp; ' ), linkStyle
return table.concat( res, ' &nbsp; ' ) -- , linkStyle
end
end
--=================================================================== |проверять!|
-- функции, по которым остались сомнения в использовании
tools.dateLength = {[''] = 10, ['1'] = 10, ['2'] = 7, ['3'] = 4}
function tools.ReparseDate ( frame )
return tools.reparseDate(
string.sub(frame.args[1], 1, tools.dateLength[frame.args[2] or ''] ) )
end
--==================================================================== |на выброс|
-- неиспользуемые функции
--[====[
function tools.flip( array, value )
    local res = {}
    for k, v in pairs( array ) do
        res[v] = value or k
    end
    return res
end
function tools.args( args )
local res, x = {}
for k,v in pairs( args ) do
x = mw.text.trim(v)
if x ~= '' then
res[k] = x
end
end
if x then
res['___HAS_ARG___'] = true
end
return res
end
function tools.cq( tables, fields, args )
return mw.ext.cargo.query( tables, fields, args )
end
--]====]


return tools
return tools

Версия от 12:20, 21 августа 2020

    Описание   


Набор вспомогательных функций для других модулей.

errorMsg

Форматирование сообщения об ошибке вызова шаблона.

text = errorMsg( tpt, errorTxt, errorAdvice )
  • tpt — имя шаблона (без префикса «Шаблон:»)
  • errorTxt — диагностика
  • errorAdvice — дополнительные сведения об ошибке («Используйте формат обращения ...»)

Функция возвращает строку, содержащее отформатированное сообщение и задание категории «Страницы с ошибкой вызова шаблона ...».

checkargs

Проверка и нормализация аргументов

modArgs, hasArg = tools.checkargs( args, names )
  • args — таблица аргументов
  • names — описание допустимых аргументов в формате: ключ_допустимого аргумента = значение_по_умолчанию

Если значение_по_умолчанию равно true, то это означает, что соответствующий аргумент не имеет значения по умолчанию. В противном случае аргументы, ключи которых отсутствуют в исходной таблице args или имеют значение пустой строки, получают указанное значение_по_умолчанию.

При успешной проверке (в исходной таблице args нет элементов с ключами, отсутствующими в names) функция возвращает таблицу modArgs со всеми элементами (включая добавленные значения по умолчанию) и признак наличия элементов в исходной таблице аргументов. Последнее полезно, чтобы предупреждать ошибки, связанные с тем, что движок MediaWiki в ходе обработки страницы не интерпретирует повторно шаблоны без параметров; для повторного парсинга необходимо наличие у шаблона хотя бы пустого параметра.

При обнаружении в исходной таблице args первого же ключа отсутствующего в names, функция возвращает пару значений nil, лишний_ключ.

При возвращении значений (кроме значений по умолчанию) осуществляется нормализация: пробельные символы в начале и конце значения убираются, пустые значения превращаются в nil.

parseDate

Преобразование текстовой даты в стандартный внутренний формат

fdate, year, month, day = tools.parseDate( indate, border )
  • indate — дата в произвольном пользовательском формате
  • border — минимальный год (XIX века!) для дат, в которых год задан двумя цифрами

Возвращает fdate в формате гггг-мм-чч и числовые значения года, месяца и дня. Для неполных дат (год или месяц+год) текстовая строка укорочена, а вместо соответствующих числовых значений возвращается nil. При пустой дате на входе возвращает пустую строку. При ошибке возвращает nil.

reparseDate

Преобразование даты в стандартном внутреннем формате гггг-мм-чч в стандартный печатный формат (чч.мм.гггг)

text = tools.reparseDate( value )
  • value — дата в стандартном внутреннем формате

Обрабатывает в том числе и неполные даты (укороченные строки). При пустой дате отдает прочерк («—»).

textDate

Преобразование даты в стандартном внутреннем формате гггг-мм-чч в текстовый формат (с месяцем прописью).

text = tools.textDate( value, p )
  • value — дата в стандартном внутреннем формате
  • p — падеж ('i' — именительный (по умолчанию), 'g' — родительный)

Возвращает текст с месяцем прописью и словом «год» в конце. Падеж значим для неполных дат. При пустой дате отдает прочерк («—»).

phrase

Преобразование текста в предложение

mText = tools.phrase( text )

Преобразование текста в предложение (первая буква делается прописной, в конце добавляется точка.

noPhrase

Преобразование текста для использования внутри предложения

mText = tools.noPhrase( text )

Преобразование текста в не-предложение (первая буква делается строчной, завершающая точка, если она есть, упраздняется).

db

Криворуко сделанный (не через метатаблицу) доступ к данным

result = tools.db( base, elem, field )

Функция возвращает элемент (запись) таблицы db с ключом elem, а если задано имя поля field — соответствующее поле этой записи. Если запись содержит поле redirect, то происходит переадресация на элемент с указанным в поле redirect ключом.

commonParams

Обработка универсальных параметров шаблонов страниц персоналий

text = tools.commonParams( addendum, reference, source )
  • addendum — дополнение
  • reference — сноска
  • source — ссылка на первоисточник

Формирует текст для выходного потока.

При наличии сносок или источников обращается к модулю {{Lua-logo-nolabel.svg RefTools}} , при наличии источников — к функции link модуля {{Lua-logo-nolabel.svg Сайт}}  (через tools.formatIfUrl, см. ниже).

formatIfUrl

Преобразование параметра в красивую ссылку, если он представляет собой URL

text, noURL = tools.formatIfUrl( whatwherefrom, txt )
  • whatwherefrom — формат ссылки ('what' — сайт, 'where' — на сайте, 'from' — ???)
  • txt — обрабатываемый параметр

Возвращает параметр (если это был URL, то преобразованный) и true в качестве второго результата, если преобразования не было. Для преобразования вызывается функция link модуля {{Lua-logo-nolabel.svg Сайт}} .

segment

Формирование ссылки на страницу места службы.

text = tools.segment( segmentName )
  • segmentName — наименование места службы

Функция возвращает ссылку в формате «[url segmentName]».

name

Добавление подкраски для индекса тезки в имени персоналии

text = tools.name( name, idx )
  • name — имя персоналии
  • idx — индекс тезки (если он не задан в первом параметре) или nil.

Функция возвращает текстовое представление имени с обрамлением индекса тезки тегом <span>.

splitName

Разбор имени, использованного для указания персоналии (на страницах документов и т. п.).

last, first, middle, idx, warning, normalized = tools.splitName( name, redlink )
  • name — имя персоналии
  • redlink — разбор выполняется для страницы несуществующего персонажа или страницы разрешения неоднозначности.

Возвращает разобранное по элементам (фамилия, имя, отчество, индекс тезки) имя. Для многословных элементов: граница фамилии определяется по запятой, а имя всегда считается однословным. Сведения об обнаруженных при разборе ошибках помещаются в массив текстовых строк warning (отсутствие ошибок — пустой массив). Последний элемент normalized, возвращаемый функцией, содержит имя, записанное в эталонной форме (инициалы с точками и проч.) без индекса тезки.

Используется модулями {{ Персона }} , {{ Упоминание }} , {{ Новый персонаж }} .

cargoString

Формирует условие для sql-запроса в зависимости от того, является ли значение пустым (IS NULL) или нет (= x).

text = tools.cargoString( value )
  • value — имя персоналии

Поскольку Cargo всегда сохраняет пустые строки как NULL, функция формирует условие в зависимости от значения либо в виде = 'value', либо IS NULL.

podvigLink

Расшифровка параметра шаблона «подвиг» (сведений с сайта ОБД МО «Подвиг народа»).

text = tools.podvigLink( str, imagesBase )
  • str — значение параметра «подвиг» (см. описание шаблона {{ Персона }} )
  • imageBase — признак использования нестандартного URL для изображений (используется в шаблоне {{ Представление }} )

Функция возвращает текстовую строку для включения в выходной текст. Раньше вторым параметром возвращался признак того, что ссылка на сайт ОБД МО указывает не на страницу награждения, а на страницу картотеки (теперь его всегда нет!)

local tools = {}

----------------------------------------------------------------------- |errorMsg|
local function enumeratePara( para )
	local res = ''
	local maxi = 0
	for i, v in ipairs( para ) do
		res = res .. ' | ' .. v
		maxi = i
	end
	for i, v in pairs( para ) do
		if not tonumber( i ) or tonumber( i ) > maxi then
			res = res .. ' | ' .. i .. ' = ' .. v
		end
	end
	return res
end

function tools.errorMsg( tpt, errorTxt, errorAdvice )
	if errorAdvice then
		errorAdvice = '<span class="nkvd-error-advice">' .. errorAdvice .. '. </span>'
	else
		errorAdvice = ''
	end
	return '<div class="nkvd-error"><span class="nkvd-error-tpt">{{ '
		.. '[[Шаблон:' .. tpt .. '|' .. tpt .. ']]' -- вместо .. Frame:getParent():getTitle()
		.. enumeratePara( mw.getCurrentFrame():getParent().args )
		.. ' }}</span><span class="nkvd-error-diag">'
		.. errorTxt .. '. </span>' .. errorAdvice .. '</div>'
		.. '[[Категория:Страницы с ошибками вызова шаблона «' .. tpt  .. '»]]'
end

---------------------------------------------------------------------- |checkargs|
function tools.checkargs( args, names )
    local res = {}
    local hasArg
    for k, v in pairs( args ) do
        hasArg = true
        v = mw.text.trim(v)
        if not names[k] then
            return nil, k
        elseif v == '' then
            if names[k] ~= true then
                res[k] = names[k]
            end
        else
            res[k] = v
        end
    end
    for k, v in pairs( names ) do
        if not res[k] then
            if v ~= true then
                res[k] = v
            end
        end
    end
    return res, hasArg
end

---------------------------------------------------------------------- |parseDate|
function tools.parseDate( indate, border )
	border = border or 1880
	if indate == '' then
		return ''
	end
	if string.match( indate, '[^%d%-%./ ]' ) then
		return nil
	end
	local a = mw.text.split( indate, '[%-%./ ]' )
	local f, d, m, y, dn, mn, yn
	if #a == 1 then
		f = #a[1] .. '--'
	elseif #a == 2 then
		f = #a[1] .. #a[2] .. '-'
	elseif #a == 3 then
		f = #a[1] .. #a[2] .. #a[3]
	else
		return nil
	end
	if f == '4--' then
		y = a[1]
	elseif f == '022' or f == '024' then
		m = a[2]; y = a[3]
	elseif f == '22-' or f == '24-' then
		m = a[1]; y = a[2]
	elseif f == '42-' or f == '420' then
		y = a[1]; m = a[2]
	elseif f == '224' or f == '222' then
		d = a[1]; m = a[2]; y = a[3]
	elseif f == '422' then
		y = a[1]; m = a[2]; d = a[3]
	else
		return nil
	end
	yn = tonumber( y )
	if #y == 2 then
		yn = yn + 1800
		if yn < border then
			yn = yn + 100
			y = '19' .. y
		else
			y = '18' .. y
		end
	end
	mn = tonumber( m or -1 )
	dn = tonumber( d or -1 )
	if dn == 0 or dn > 31 or mn == 0 or mn > 12 then
		return nil
	end
	--TODO: Не хватает честной проверки числа в зависимости от месяца
	return table.concat( { y, m, d }, '-' ), y, m, d
end

-------------------------------------------------------------------- |reparseDate|
function tools.reparseDate( value )
	if #value == 10 then
		return string.sub( value, 9, 10 ) .. '.'
			.. string.sub( value, 6, 7 ) .. '.'
			.. string.sub( value, 1, 4 )
	elseif #value == 7 then
		return string.sub( value, 6, 7 ) .. '.'
			.. string.sub( value, 1, 4 )
	elseif #value == 4 then
		return  string.sub( value, 1, 4 )
	end
	return '—'

end

----------------------------------------------------------------------- |textDate|
local mes = {
	i = { 'январь', 'февраль',  'март',   'апрель',  'май',  'июнь',  'июль',  'август',   'сентябрь',  'октябрь',  'ноябрь',  'декабрь', 'год'  },
	g = { 'января', 'февраля',  'марта',  'апреля',  'мая',  'июня',  'июля',  'августа',  'сентября',  'октября',  'ноября',  'декабря', 'года' },
}
function tools.textDate( value, p )
	p = p or 'i'
	if #value == 10 then
		return tonumber( string.sub( value, 9, 10 ) ) .. ' '
			.. mes.g[tonumber( string.sub( value, 6, 7 ) )] .. ' '
			.. string.sub( value, 1, 4 ) .. ' года'
	elseif #value == 7 then
		return mes[p][tonumber( string.sub( value, 6, 7 ) )] .. ' '
			.. string.sub( value, 1, 4 ) .. ' года'
	elseif #value == 4 then
		return  value .. ' ' ..  mes[p][13]
	end
	return '—'

end

------------------------------------------------------------------------- |phrase|
function tools.phrase (text)
	text = mw.text.trim( text )
	if text == '' then
		return ''
	end
	text = mw.ustring.upper( mw.ustring.sub( text, 1, 1) ) .. mw.ustring.sub( text, 2, -1 )
	local z = mw.ustring.sub( text, -1, -1 )
	if z ~= '.' and z ~= '!' and z ~= '?' then
		return text .. '.'
	end
	return text
end

----------------------------------------------------------------------- |noPhrase|
function tools.noPhrase (text)
	text = mw.text.trim( text )
	text = mw.ustring.lower( mw.ustring.sub( text, 1, 1) ) .. mw.ustring.sub( text, 2, -1 )
	if mw.ustring.sub( text, -1, -1 ) == '.'  then
		return mw.ustring.sub( text, 1, -2 )
	end
	return text
end

----------------------------------------------------------------------------- |db|
function tools.db( base, elem, field )
	local el = base[elem]
	if not el then
		return nil
	end
	if type(el) == 'table' and el.redirect then
		return tools.db( base, el.redirect, field )
	elseif field then
		return el[field]
	else
		return el
	end
end

------------------------------------------------------------------- |commonParams|
function tools.commonParams( addendum, reference, source )
	if ( addendum or '' ) ~= '' then
		addendum = ' <span class="nkvd-addendum">('
			.. tools.noPhrase( addendum )  .. ')</span>'
	else
		addendum = ''
	end
	if ( reference or '' ) ~= '' or ( source or '' ) ~= '' then
		local refTools = require( 'Module:RefTools' )
		reference = refTools.makeRef( reference )
		source = refTools.makeRef( tools.formatIfUrl( 'what', source ), true )
	else
		reference = ''
		source = ''
	end
	return addendum .. reference .. source
end

-------------------------------------------------------------------- |formatIfUrl|
function tools.formatIfUrl( whatwherefrom, txt )
	if not txt then
		return
	end
	if string.sub( txt, 1, 7 ) ~= 'http://'
			and string.sub( txt, 1, 8 ) ~= 'https://'
			and string.sub( txt, 1, 2 ) ~= '//' then
		return txt, true
	end
	if string.find( txt, ' ' ) then
		return txt, true
	end
	return require( 'Модуль:Сайт' ).link( whatwherefrom, txt )
end

------------------------------------------------------------------------ |segment|
function tools.segment( s )
	if ( s or '' ) ~= '' then
		return '<i>[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = 'segment', value = s } ) )
			.. ' ' .. s .. ']</i>'
	end
end

--------------------------------------------------------------------------- |name|
function tools.name( name, idx )
	local root
	if not idx then
		root, idx = string.match( name, '^(.+) (%([IVX%-]+%))$' )
		if not root then
			return name
		end
	else
		root = name
	end

	if idx == '' then
		return root
	else
		return root .. ' <span class="nkvd-idx">' .. idx .. '</span>'
	end
end

---------------------------------------------------------------------- |splitName|
function tools.splitName( Name, redlink )
	local name = Name
	local l, f, m, d
	local warn = {} -- мягкие предупреждения начинаются с пробела
	if string.find( name, '  ', 1, true ) then
		warn[#warn+1] = 'В имени персоны нельзя ставить несколько пробелов подряд'
		name = string.gsub( name, '  +', ' ' )
	end
	name = string.gsub( name, '%.%.%.([^%.])', '#\1' )
	name = string.gsub( name, '%.%.%.$', '#' )
	if string.match( name .. ' ', '[,#%.][^ ]' ) then
		warn[#warn+1] = 'После запятой, точки и многоточия пробелы обязательны'
		name = string.gsub( name, '([,#%.])([^ ])', '%1 %2' )
	end

	local tmp = string.find( name, ' (', 1, true )
	if tmp then
		name, d = string.sub( name, 1, tmp-1 ), string.sub( name, tmp+1, -1 )
		if not string.match( d, '^%([IVX]+%)$' ) and ( not redlink or d ~= '(*)' ) then
			return nil, 'Номер тезки должен записываться в скобках римскими цифрами'
		end
	end
	tmp = string.find( name .. ' ', ', ', 1, true )
	if tmp then
		l, f = string.sub( name, 1, tmp-1 ), string.sub( name, tmp+2, -1 )
	else
		l, f = name, ''
		if string.find( l, ' ', 1, true ) then
			warn[#warn+1] = ' Фамилия состоит из нескольких слов. Если это действительно так,'
				.. ' поставьте после нее запятую, чтобы избавиться от этого предупреждения'
		end
	end
	if string.sub( l, 1, 1 ) == '-' then
		warn[#warn+1] = 'Вместо минуса спереди используйте шаблон «персона*»'
	end
	if mw.ustring.match( f, '[а-я][а-я]%.$' ) then
		warn[#warn+1] = 'Вместо точки после ФИО используйте шаблон «персона?»'
	end
	f = string.gsub( f, '[#%.]', '' )
	if f ~= '' then
		tmp = string.find( f, ' ', 1, true )
		if tmp then
			f, m = string.sub( f, 1, tmp-1), string.sub( f, tmp+1, -1 )
		end
	end
	name = l
	m = m or ''
	if f ~= '' or m ~= '' then
		name = name .. ','
		if f == '' then
			name = name .. ' ...'
		elseif mw.ustring.len (f) == 1 then
			name = name .. ' ' .. f .. '.'
		else
			name = name .. ' ' .. f
		end
		if m ~= '' then
			name = name .. ' ' .. m
		end
		if mw.ustring.len (m) == 1 then
			name = name .. '.'
		end
	end
	if d then
		tmp = name .. ' ' .. d
	else
		tmp = name
	end
	if tmp ~= Name and #warn == 0 then
		warn[#warn+1] = ' Эталонная форма записи этого имени — «' .. tmp
			.. '». Вы уверены, что написали правильно?'
	end

	return  l, f, m, d, warn, name
end

-------------------------------------------------------------------- |cargoString|
function tools.cargoString( s )
	if ( s or '' ) == '' then
		return ' IS NULL'
	end
	return '="' .. s .. '"'
end

--------------------------------------------------------------------- |podvigLink|
function tools.podvigLink( str, imagesBase )
	if (str or '') == '' or string.sub(str, 1, 1) == '[' then
		return str
	end
	local pods = mw.text.split( str, '[%s]*,[%s]*' )
	local tabtext = {
		['+'] = {2, ', имеется наградной лист', },
		['-'] = {0, ', наградной лист отсутствует', },
		['/'] = {1, ', имеется только «описание подвига»', },
		['%'] = {1, ', имеется ссылка только на «описание подвига»', },
		['' ] = {2, '', },
	}
	local images = mw.site.server .. '/images'
	local imagesP = mw.site.server .. '/images/obdmo/saved'
	local imagesB = 'http://localhome.raczynski.ru/tools/podvig/scan.php?k=1*4&l='

	local res = {}
	local x, y, tmp, ico
	local linkStyle, linkFull -- Style - 2/1/0 - картотека/представление/награждение, full - 0/1 - пустой/красим
	for _, podvig in ipairs( pods ) do
		if podvig == '' then
		elseif string.sub( podvig, 1, 1 ) == '/' then
			x = string.gsub( podvig, '%s+', ' ' )
			res[#res+1] = '<span class=image-store data-image="' .. x .. '"></span>'
--			x = mw.text.split( podvig, '[%s]+' )
--			y = {}
--			if #x < 2 then
--				res[#res+1] = '<i class="error fa fa-question"></i>'
--			else
--				for i = 2, #x do
--					if imagesBase then
--						tmp = imagesB .. x[1] .. '&n=' .. x[i]
--						ico = ''
--					else
--						if string.sub( x[i], -1, -1 ) == '-' then
--							tmp = string.sub( '00000000' .. string.sub( x[i], 1, -2 ), -8, -1 ) .. '_1'
--							ico = '-o'
--						else
--							tmp = string.sub( '00000000'..x[i], -8, -1 )
--							ico = ''
--						end
--						tmp = imagesP .. x[1] .. '/' .. tmp .. '.jpg'
--					end
--					y[#y+1] =  '[' .. tmp
--						.. ' <i class="fa fa-file-text' .. ico
--						.. '"  style="color:gray; font-size:82%;" title="Сохраненные материалы"></i>]'
--				end
--				res[#res+1] = '<span class=nkvd-hide-inline> ' .. table.concat( y, ' ' ) .. '</span>'
--			end
		else
			x, y = string.match( podvig, '^(%d+) *([%+%-%*%%/#!]*)$' )
			if not x then
				linkStyle = -1
			else
				if y == '#' then
					linkStyle, linkFull = 2, 0
					y = ' в картотеке награждений'
				elseif y == '!' then
					linkStyle, linkFull = 3, 0
					y = ''
				else
					linkFull, linkStyle = string.gsub( y, '%*', '' )
					y = tabtext[linkFull]
					if not y then
						linkStyle = -1
					else
						linkFull = y[1]
						y = y[2]
					end
				end
			end
			if linkStyle == -1 then
				res[#res+1] = '<i class="error fa fa-question"></i>'
			else
				if linkFull == 0 then
					linkFull = '-o'
				elseif linkFull == 1 then
					linkFull = '-half-o'
				else
					linkFull = ''
				end
				tmp = ''
				if linkStyle ~= 2 then
					if linkStyle == 0 then
						tmp = 'nagrazhdenie'
					elseif linkStyle == 3 then
						tmp = 'yubileinaya_kartoteka'
					else
						tmp = 'predstavlenie'
					end
					res[#res+1] = ' &nbsp;[https://pamyat-naroda.ru/heroes/podvig-chelovek_' .. tmp
						.. x .. '/ <i class="fa fa-star' .. linkFull
						.. '" style="color:#D33738; font-size:82%;" title="Информация о награждении на сайте «Память народа»'
						.. y ..'"></i>] '
						.. '[http://podvignaroda.ru/#?id='
						.. x .. ' <i class="fa fa-star' .. linkFull
						.. '" style="color:gray; font-size:82%;" title="Информация о награждении на сайте «Подвиг народа»'
						.. y ..'"></i>]'
						.. ' <span class=local-id data-id="' .. x .. '"></span>'
--						.. '<span class=nkvd-hide-inline> [http://localhome.raczynski.ru/tools/podvig?n=' .. x
--						.. ' <span style="color:#ffdd75" title="Sorry, internal use only">&nabla;</span>]</span>'

--					linkStyle = false
				else
					res[#res+1] = ' &nbsp;[http://podvignaroda.ru/#?id='
						.. x .. '  <i class="fa fa-folder-o'
						.. '" style="color:gray; font-size:82%;" title="Информация о награждении на сайте «Подвиг народа»'
						.. y ..'"></i>]'
						.. ' <span class=local-id data-id="' .. x .. '"></span>'
--						.. '<span class=nkvd-hide-inline> [http://localhome.raczynski.ru/tools/podvig?n=' .. x
--						.. ' <span style="color:#ffdd75" title="Sorry, internal use only">&nabla;</span>]</span>'

--					linkStyle = true
				end
			end
		end
	end

	return table.concat( res, ' &nbsp; ' ) -- , linkStyle
end



--=================================================================== |проверять!|
-- функции, по которым остались сомнения в использовании

tools.dateLength = {[''] = 10, ['1'] = 10, ['2'] = 7, ['3'] = 4}
function tools.ReparseDate ( frame )
	return tools.reparseDate(
		string.sub(frame.args[1], 1, tools.dateLength[frame.args[2] or ''] ) )
end

--==================================================================== |на выброс|
-- неиспользуемые функции
--[====[
function tools.flip( array, value )
    local res = {}
    for k, v in pairs( array ) do
        res[v] = value or k
    end
    return res
end

function tools.args( args )
	local res, x = {}
	for k,v in pairs( args ) do
		x = mw.text.trim(v)
		if x ~= '' then
			res[k] = x
		end
	end
	if x then
		res['___HAS_ARG___'] = true
	end
	return res
end

function tools.cq( tables, fields, args )
	return mw.ext.cargo.query( tables, fields, args )
end
--]====]


return tools