Модуль:CatNav

Материал из Кадровый состав НКВД 1935-1939
Перейти к: навигация, поиск

Для документации этого модуля может быть создана страница Модуль:CatNav/doc

local pp ={}
local LIMIT = 200
-- 'fields=prize,COUNT(DISTINCT nLast,IFNULL(nFirst,""),IFNULL(nMiddle,""),IFNULL(nDisambig,""))'
local function navq( journal, fieldFix, valueFix, fieldVar, valueFrom, valueTo, letter, cond )
	local order = ''
	local mainCond = fieldFix .. ' = "' .. valueFix .. '"'
	if fieldFix == 'segment' then
		local synA = mw.loadData( 'Модуль:CatNav/segment/sub' )
		if synA[valueFix] then
			mainCond = { mainCond }
			for _, syn in ipairs( synA[valueFix] ) do
				mainCond[#mainCond+1] = 'segment = "' .. syn .. '"'
			end
			mainCond = '(' .. table.concat( mainCond, ' OR ' ) .. ')'
		end
	end

	local where = { mainCond, cond }
	if ( letter or '' ) ~= '' then
		where[#where+1] = fieldVar .. ' LIKE "' .. letter .. '%"'
	end
	if ( valueTo or '' ) ~= '' then
		where[#where+1] = fieldVar .. ' < "' .. valueTo .. '"'
		order = ' DESC'
	elseif ( valueFrom or '' ) ~= '' then
		where[#where+1] = fieldVar .. ' >' .. ' "' .. valueFrom .. '"'
	end
	where = table.concat( where, ' AND ' )
	local query = mw.ext.cargo.query(
		journal,
		fieldVar,
		{
			where = where,
			orderBy = fieldVar .. order,
			limit = LIMIT+1,
			groupBy = fieldVar,
		}
	)
	local more = #query == LIMIT+1
	query[LIMIT+1] = nil
	if order ~= '' then
		for i = 1, #query/2 do
			query[i], query[#query-i+1] = query[#query-i+1], query[i]
		end
	end
--	query[#query+1] = { person = where }
	return query, more
end

local function rankFn( x )
	local rank, gen = mw.ustring.match( x, '^([^:]+):([%d]+)$' )
	if not rank then
		rank = x
	end
	local rankT = require('Module:Tools').db( require('Модуль:Звания'), rank )
	local d = rankT.diap
	rankT = rankT['кто']

	local plus, cond = ''
	if gen and d then
		gen = tonumber( gen )
--		if d[#d][2] ~= '!' then
--			d[#d+1] = { '2137-12-31', '!' }
--		end
		if gen == 0 then
			plus = ' (анахронизмы)'
			cond = 'subrank = "0"'
		elseif gen < #d then
			plus = d[gen][2]
			cond = 'subrank = "' .. gen .. '"'
		end
	elseif d then
		plus = ' (все периоды)'
	end
	return rankT .. plus, rank, cond
end

function pp.Nav( frame )
	local args = frame.args
	local ctg, val, start, stop, letter
		= mw.text.trim( args[1] ), mw.text.trim( mw.uri.decode( args[2] ) ),
			mw.text.trim( mw.uri.decode( args[3] ) ), mw.text.trim( mw.uri.decode( args[4] ) ),
			mw.text.trim( mw.uri.decode( args[5] ) )
	local tab = {
		rank  = { 'ranks_table', 'rank', 'nFull', 'Звание', rankFn },
		prize = { 'prizes_table', 'prize', 'nFull', 'Награда', nil },
		segment = { 'designations_table', 'segment', 'nFull', 'Место службы', nil },
		women = { 'persons', 'gender', '_pageName', 'Пол', nil },
	}
	do
--		return '((( ' .. ctg .. ' /// ' .. val .. ' )))'
	end
--	include = include == '1'

	local paras = tab[ctg]
	if not paras then
		return '<p class=error>Неизвестный класс навигации «' .. ( ctg or '???' ) .. '»!</p>'
	end
	local valT, valS, cond = val, val
--	local ti, cond = val
	if paras[5] then
		valT, valS, cond = paras[5]( val )
	end

	local out = { '{{DISPLAYTITLE:НКВД: ' .. paras[4] .. ' — ' .. valT .. '}}\n' }
	out[#out+1] = '<div style="float:right; margin: 0 0 1em 1em" title="Редактировать предисловие">[{{fullurl:НКВД:'
		.. paras[4] .. ':' .. valT .. '|action=edit}} <i class="fa fa-pencil"></i>]</div>\n'
	if mw.title.new( paras[4] .. ':' .. valT, 'НКВД' ).exists then
		out[#out+1] = '{{НКВД:' .. paras[4] .. ':' .. valT .. '}}\n'
	elseif string.find( valT, 'дивизия', 1, true ) or string.find( valT, 'бригада', 1, true ) or string.find( valT, 'корпус', 1, true ) then
		local tmp = string.gsub( valT, ' (авиа[^ ]+)', { ['авиадивизия'] = ' авиационная дивизия', ['авиабригада'] = ' авиационная бригада', ['авиакорпус'] = ' авиационный корпус', }, 1 )
		tmp = string.gsub( tmp, 'Войска Польского', '(Войско Польское)', 1 )
		tmp = string.gsub( tmp, 'мотоштурмовая', 'моторизованная штурмовая', 1 )
		tmp = string.gsub( tmp, 'мотоинженерная', 'моторизованная инженерная', 1 )
		tmp = string.gsub( tmp, ' ПТО', ' противотанковой обороны', 1 )
		out[#out+1] = '<i>Информацию о соединении см. в [[rkka:' .. tmp .. '|указателе частей и соединений РККА]].</i><br>'
	end
	local tmp
	local counter = 'COUNT(DISTINCT ' .. paras[3] .. ')'
	if ( letter or '' ) == '' and start == '' and stop == '' then
		tmp = mw.ext.cargo.query(
				paras[1],
				counter,
				{
					where = table.concat( {paras[2] .. ' = "' .. valS .. '"', cond }, ' AND ' )
				}
			)
		out[#out+1] = '<p>Всего персоналий: ' .. tmp[1][counter] .. '.</p>'
	end

	out[#out+1] = '<table class="nkvd-ltr-tab" id="nkvd-ltr-tab"><tr>'
	local url = mw.title.getCurrentTitle().prefixedText
	local baseurl = tostring( mw.uri.fullUrl( url, { class = ctg, value = val, } ) )
	if ( letter or '' ) == '' then
		tmp = '-cur'
	else
		tmp = ''
	end
	out[#out+1] = '<td class="nkvd-ltr' .. tmp ..'">[' .. baseurl .. ' Все]</td>'

	local letters = { 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ж', 'З', 'И', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Э', 'Ю', 'Я', }
	for _, ltr in ipairs( letters ) do
		if ltr == letter then
			tmp = '-cur'
		else
			tmp = ''
		end
		out[#out+1] = '<td class="nkvd-ltr' .. tmp ..'" style="width: 3.4%">[' .. baseurl
			.. '&letter=' .. mw.uri.encode(ltr) .. '#nkvd-ltr-tab ' .. ltr .. ']</td>'
	end
	out[#out+1] = '</tr></table>'

	local query, more = navq( paras[1], paras[2], valS, paras[3], start, stop, letter, cond )
	local diagnose, prevP, nextP
	if #query == 0 then
		diagnose = 'Нет персоналий по этому запросу'
	elseif start == '' and stop == '' then
		nextP = more
	elseif start ~= '' then
		prevP = true
		nextP = more
	else
		prevP = more
		nextP = true
	end

	if #query == 0 then
		start, stop = stop, start
		include = '1'
	else
		start, stop = query[#query].nFull, query[1].nFull
		include = nil
	end

	if prevP then
		out[#out+1] = '<div style="float:left"> ['
			.. tostring( mw.uri.fullUrl( url, { class = ctg, value = val, to = query[1].nFull, letter = letter } ) )
			.. '#nkvd-ltr-tab (предыдущая страница)] </div>'
	end
	if nextP then
		out[#out+1] = '<div style="float:right"> ['
			.. tostring( mw.uri.fullUrl( url, { class = ctg, value = val, from = query[#query].nFull, letter = letter } ) )
			.. '#nkvd-ltr-tab (следующая страница)] </div>'
	end
	out[#out+1] = '<br style="clear:both">'
	if diagnose then
		out[#out+1] = '<p>' .. diagnose .. '</p>\n'
	end

	out[#out+1] = '<div style="columns: 4 20em; -moz-columns:4 20em; -webkit-columns: 4 20em;">\n'
	for _, person in ipairs( query ) do
--		out[#out+1] = '* [[' .. person.nFull .. ']]\n'
		out[#out+1] = '* [[' .. person[paras[3]] .. ']]\n'	end
	out[#out+1] = '</div>'
	return frame:preprocess( table.concat( out ) )
end

function pp.Cat( frame )
	local class = mw.ext.luaglobal.get( 'CatClass' )
	local args = frame:getParent().args
	local value = mw.text.trim( args[1] or '' )
	if not class then
		mw.ext.luaglobal.set( 'CatClass', value )
--		mw.ext.luaglobal.set( 'CatClassValue', { 0 } )
		return ''
	end

	local text = mw.text.trim( args[2] or '' )

	local tablo = mw.loadData( 'Module:CatNav/' .. class )
	local checking = mw.title.getCurrentTitle().subpageText == 'вне перечня'

	if class ~= 'rank' then
		if value ~= '' then
			if text == '-' then
--				return tablo[value] or '—'
				return '[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = class, value = value } ) )
					.. ' ' .. (tablo[value] or '—') .. ']'
			end
			text = text or ''
			if string.match( text, '%%' ) then
				return mw.ustring.gsub( text, '%%[ln]',
					{ 	['%l'] = tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = class, value = value } ) ),
						['%n'] = tablo[value] or 0 , } ) .. ''
			end

			if text == '' then
				text = value
			end

			if tablo[value] then
				mw.ext.luaglobal.add( 'CatClassValue', value )
				if checking then
					return
				end
				return '[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = class, value = value } ) )
					.. ' ' .. text .. '] (' .. tablo[value] .. ')'
			else
				if checking then
					return
				end
				return '<span style="color:red">' .. value .. '</span> (—)'
			end
		end
		local tablus = mw.ext.luaglobal.get( 'CatClassValue' )
		local flip = {}
		for _,v in ipairs( tablus ) do
			flip[v] = true
		end
		tablus = {}
		for v,n in pairs( tablo ) do
			if not flip[v] then
				tablus[#tablus+1] = '[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = class, value = v } ) )
					.. ' ' .. v .. '] (' .. n .. ')'
			end
		end
		if #tablus ~= 0 then
			table.sort( tablus )
			return 'Отсутствуют в перечне (' .. #tablus .. '): ' .. table.concat( tablus, ', ' )
		end
		return ''
	end

	local rankTab = mw.loadData( 'Модуль:Звания' )
	if value ~= '' then
		local rank, gen = mw.ustring.match( value, '^([^:]+):([%d]+)$' )
		if not rank then
			rank = value
		else
			gen = tonumber( gen )
		end

		local rankTval = require('Module:Tools').db( rankTab, rank ) -- rankTab[rank] --
		if not rankTval then
			return '<span class=error>' .. rank .. ' — отсутствует в таблице званий</span>'
		end

		local tTablo = tablo[rank]
		if tTablo then
			--[[
			gen	#t	res		text
			-	1	t[1]	r
			-	n	sum(t)	r [не пишем «все периоды»]
			x	x	t[x]	rx
			--]]
			local k = 0
			if not gen then
				for _, v in pairs( tTablo ) do
					k = k + v
				end
				if text == '' then
					text = rankTval['кто']
				end
			else
				k = tTablo[tostring( gen )]
				if text == '' then
					if gen == 0 then
						text = rankTval['кто'] .. ' (анахронизмы)'
					else
						text = rankTval['кто'] .. rankTval.diap[gen][2]
					end
				end
			end
			mw.ext.luaglobal.add( 'CatClassValue', { rank, gen or -1 } )
			return '[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = class, value = value } ) )
				.. ' ' .. text .. '] (' .. k .. ')'
		else
			return '<span style="color:red">' .. value .. '</span> (—)' -- mw.dumpObject(tablo) --
		end
	end
	local tablus = mw.ext.luaglobal.get( 'CatClassValue' )
	do
--		return mw.dumpObject( tablus )
	end

	local flip = {}
	for _,v in ipairs( tablus ) do
		flip[v[1]] = flip[v[1]] or {}
		flip[v[1]][v[2]] = true
	end
	tablus = {}
	for v,n in pairs( tablo ) do
		if not flip[v] then
			tablus[#tablus+1] = '[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = class, value = v } ) )
				.. ' ' .. v .. ']'
		else
			for x, u in pairs( n ) do
				if x ~= '0' and not flip[v][-1] and not flip[v][tonumber( x )] then
					tablus[#tablus+1] = '[' .. tostring( mw.uri.fullUrl( 'НКВД:Выборка', { class = class, value = v .. ':' .. x } ) )
						.. ' ' .. v .. ':' .. x .. ']'
				end
			end
		end
	end
	if #tablus ~= 0 then
		table.sort( tablus )
		return 'Отсутствуют в перечне (' .. #tablus .. '): ' .. table.concat( tablus, ', ' )
	end

end





return pp

--[[
3) надо на странице персон рисовать квазикатегорию — придумать где
4) нужны аналоги лишних и отсутствующих категорий.
--]]