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

Материал из Кадровый состав НКВД 1935-1939
Перейти к навигации Перейти к поиску
Нет описания правки
Нет описания правки
Строка 235: Строка 235:
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
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
end
end


return tools
return tools

Версия от 18:29, 11 февраля 2017

    Описание   


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

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 = {}

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()
		.. 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 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.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.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

function tools.parseDate( indate, border )
	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

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

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


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

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

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



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 )
	if ( addendum or '' ) ~= '' then
		addendum = ' <span class="nkvd-addendum">('
			.. tools.noPhrase( addendum )  .. ')</span>'
	else
		addendum = ''
	end
	local refTools = require( 'Module:RefTools' )

	reference = refTools.makeRef( reference )
	source = refTools.makeRef( source, true )
	return addendum .. reference .. source
end

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

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

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

return tools