Модуль:Секции документа

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

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

local pp = {}
local global = mw.ext.luaglobal;
tools = require( 'Модуль:Tools' )
refTools = require( 'Модуль:RefTools' )
local doctools = require( 'Модуль:DocTools' )
local abbr = mw.loadData( 'Модуль:Аббревиатуры' )
local Doc
local Frame, Args
local rankTable = mw.loadData( 'Модуль:Звания' )
local prizeTable = mw.loadData( 'Модуль:Награды' )
global.strict( true )

--[=[
Проверка совместимости заголовка с существующим стеком
* header — вносимый заголовок
* ourHeaders — набор заголовков, которые могут сочетаться с новым
* ourAction — конкретные действия (соответствующие заголовку «действие»), совместимые с новым заголовком

Возвращает nil (все хорошо) или строку — проблемный элемент стека (заголовок, действие)
--]=]
local function checkStack( header, compatSections, compatActions )
	-- Делаем проверку на действия независимо от структуры
	if compatActions and Doc.h2v['действие'] then
        if not compatActions[Doc.h2v['действие']] then
			return Doc.h2v['действие']
		end
		compatSections['действие'] = true
	end
	if Doc.stream then
		local new_n2h = {}
		for _, h in ipairs( Doc.n2h ) do
			if compatSections[h] then
				table.insert (new_n2h, h)
			else
				Doc.h2v[h] = nil
			end
		end
		Doc.n2h = new_n2h
		return nil
	else
		local k = 1
		while k <= #Doc.n2h do
			if Doc.n2h[k] == header then
				break
			else
				if not compatSections[Doc.n2h[k]] then
					return Doc.n2h[k]
				end
				k = k + 1
			end
		end
		local n = #Doc.n2h
		while k <= n do
			Doc.h2v[Doc.n2h[k]] = nil
			Doc.n2h[k] = nil
			k = k + 1
		end
		return nil
	end
end

local function doIt( action, compatSections, frame )
	local args, tmp = tools.checkargs( frame:getParent().args,
        { true, ['комментарий'] = true, ['сноска'] = true,
			['каждому'] = true, ['каждому/награда'] = true,
			['каждому/должность'] = true, ['каждому/должность+'] = true,
			['каждому/звание'] = true, ['каждому/звание+'] = true,
			} )
    if not args or args[1] then
        if args then
            tmp = args[1]
        end
        return tools.errorMsg( action,
            'Недопустимый параметр «' .. tmp .. '»')
    elseif not tmp then
		return tools.errorMsg( action,
			'Шаблон непременно должен иметь параметр (хотя бы пустой)' )
	end
	Doc = global.get( 'gDoc' )
	if not Doc then
		return tools.errorMsg( action,
			'Первым на странице должен размещаться шаблон {{ Документ }}' )
	end
	tmp = checkStack( 'действие', compatSections )
	if tmp then
		return tools.errorMsg ( action,
			'Действие «' .. action .. '» не может указываться внутри секции «' .. tmp .. '»')
	end
	table.insert( Doc.n2h, 'действие' )
	Doc.h2v['действие'] = action
	global.set( 'gDoc', Doc )
--	global.set( 'gUniref-действие', args['каждому'] )
	global.set( 'gUniref-действие', refTools.collect( args, 'каждому' ) )
	return '<p class="nkvd-doc-action nkvd-doc-level-' .. #Doc.n2h .. '">'
		.. mw.title.new(frame:getParent():getTitle(), '') .text -- ( args['текст'] or frame.args['текст'] or action )
		.. doctools.endRecord( args )
end


local function paramCheck( sectionName, compatSections, compatActions, argsSet )
	Doc = global.get( 'gDoc' )
	if not Doc then
		return nil, 'Первым на странице должен размещаться шаблон {{ Документ }}'
	end
	local tmp = checkStack( sectionName, compatSections, compatActions )
	if tmp then
		return nil, 'Секция «' .. sectionName .. '» не может находиться внутри секции «' .. tmp .. '»'
	end
    Args, tmp = tools.checkargs( Args,
        argsSet or { true, ['комментарий'] = true, ['сноска'] = true,
					['каждому'] = true, ['каждому/награда'] = true,
					['каждому/должность'] = true, ['каждому/должность+'] = true,
					['каждому/звание'] = true, ['каждому/звание+'] = true,
					} )
    if not Args then
        return nil, 'Неизвестный параметр «' .. tmp .. '»'
    end
	if not Args[1] then
		return nil, 'Не задан основной параметр'
	end
	return Args[1]
end

local function paramSet( value, paramName, paramClass, paramText )
	table.insert( Doc.n2h, paramName )
	Doc.h2v[paramName] = value
	global.set( 'gDoc', Doc )
--	global.set( 'gUniref-' .. paramName, Args['каждому'] )
	global.set( 'gUniref-' .. paramName, refTools.collect( Args, 'каждому' ) )

--	value = mw.ustring.gsub( paramText, '$1', value) -- нужен ли тут текст?

	return '<p class="nkvd-doc-' .. paramClass .. ' nkvd-doc-level-' .. #Doc.n2h .. '">'
		.. (paramText or value) .. doctools.endRecord( Args )
end
--[[---------------------------------------------------------------]]-- Параграф
pp['Параграф'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
	Doc = global.get( 'gDoc' )
	if not Doc then
		return nil, 'Первым на странице должен размещаться шаблон {{ Документ }}'
	end
	local tmp = mw.text.trim( Args[1] or '' )
    if tmp == '' then
		return tools.errorMsg( 'параграф',
			'Шаблон непременно должен иметь параметр ' )
	end
	Doc.h2v, Doc.n2h = {}, {}
	global.set( 'gDoc', Doc )
	return '<p class="nkvd-doc-paragraph">§ ' .. tmp .. '</p>'
end


--[[---------------------------------------------------------------]]-- Название
pp['Название'] = function ( frame )
	local tmp = mw.text.trim( frame:getParent().args[1] or '' )
	global.set( 'gDocAlias', tmp )
	return '<h3>' .. tmp .. '</h3>\n'
end


--[[----------------------------------------------------------------]]-- Награда
pp['Награда'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
	local value, errMsg = paramCheck( 'награда',
		{ ['подразделение'] = true, ['место службы'] = true, ['дата'] = true,  },
		{ ['наградить'] = true, ['лишить награды'] = true } )
	if not value then
		return tools.errorMsg( 'награда', errMsg )
	end
	local text = tools.db( prizeTable, value, 'чем' )
	if not text then
		return tools.errorMsg( 'награда', 'Нет такой награды' )
	end
	return paramSet( value, 'награда', 'prize', text )
end

--[[-----------------------------------------------------------------]]-- Звание
pp['Звание'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
	local value, errMsg = paramCheck( 'звание',
		{ ['подразделение'] = true, ['место службы'] = true, ['звание+'] = true },
		{ ['присвоить звание'] = true } )
	if not value then
		return tools.errorMsg( 'звание', errMsg )
	end
	local text = tools.db( rankTable, value, 'кому' )
	if not text then
		return tools.errorMsg( 'звание', 'Нет такого звания' )
	end
	return paramSet( value, 'звание', 'x-rank', text )
--	return paramSet( value, 'звание', 'rank' )
end

--[[----------------------------------------------------------------]]-- Звание+
pp['Звание+'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
	local value, errMsg = paramCheck( 'звание+',
		{ ['подразделение'] = true, ['место службы'] = true, ['звание'] = true },
		{ ['присвоить звание'] = true } )
	if not value then
		return tools.errorMsg( 'звание+', errMsg )
	end
	local text = tools.db( rankTable, value, 'кого' )
	if not text then
		return tools.errorMsg( 'звание', 'Нет такого звания' )
	end
	return paramSet( value, 'звание+', 'rank', text )
end

--[[-------------------------------------------------------------------]]-- Дата
pp['Дата'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
	local value, errMsg = paramCheck( 'дата',
		{ ['подразделение'] = true, ['место службы'] = true,
			['увольнение'] = true, ['награда'] = true,  },
		{ ['назначить'] = true, ['уволить'] = true, ['уволить и лишить звания'] = true,
			['освободить от должности'] = true, ['наградить'] = true, } )
	if not value then
		return tools.errorMsg( 'дата', errMsg )
	end
	value = tools.parseDate( value, 1900 )
	if not value then
		return tools.errorMsg ( 'дата', 'Неправильный формат даты' )
	end
	if Doc.h2v['действие'] == 'наградить' then
		return paramSet( value, 'дата', 'date', tools.reparseDate( value ) )
	end
	return paramSet( value, 'дата', 'date', 'c ' .. tools.reparseDate( value ) )
end

--[[----------------------------------------------------------]]-- Подразделение
pp['Подразделение'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
	local value, errMsg = paramCheck( 'подразделение',
		{ ['действие'] = true, ['звание'] = true, ['звание+'] = true, ['награда'] = true,
			['дата'] = true, ['увольнение'] = true, ['место службы'] = true } )
	if not value then
		return tools.errorMsg( 'подразделение', errMsg )
	end
	return paramSet( value, 'подразделение', 'unit', 'по подразделению ' .. value )
end

--[[-----------------------------------------------------------]]-- Место службы
pp['Место службы'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
	local value, errMsg = paramCheck( 'место службы',
		{ ['действие'] = true, ['звание'] = true, ['звание+'] = true, ['награда'] = true,
			['дата'] = true, ['увольнение'] = true, ['подразделение'] = true } )
	if not value then
		return tools.errorMsg( 'место службы', errMsg )
	end
	value = doctools.abbr( value, abbr.segm )
	return paramSet( value, 'место службы', 'segment', tools.segment( value ) )
end

--[[-------------------------------------------------------------]]-- Увольнение
-- Увольнение ( резерв/запас/отставка/вовсе/см.текст , статья , текст )
pp['Увольнение'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
	local dismissDb = mw.loadData('Модуль:Виды увольнения')
	local dir, errMsg = paramCheck( 'увольнение',
		{ ['подразделение'] = true, ['место службы'] = true, ['дата'] = true },
		{ ['уволить'] = true, ['уволить и лишить звания'] = true },
        { '?', ['статья'] = '', ['обоснование'] = '',
            ['комментарий'] = true, ['сноска'] = true,
			['каждому'] = true, ['каждому/награда'] = true,
			['каждому/должность'] = true, ['каждому/должность+'] = true,
			['каждому/звание'] = true, ['каждому/звание+'] = true,
			}
        )
	if not dir then
		return tools.errorMsg( 'увольнение', errMsg )
	end
	local dirTxt = dismissDb.direction[dir]
	if not dirTxt then
		return tools.errorMsg ( 'увольнение', 'Первый параметр может принимать значения'
			.. ' «резерв», «запас», «отставка» или «вовсе»')
	end

	dirTxt = dismissDb.dirParam[dirTxt].txt
	if dir == '?' then
		dirTxt = dirTxt .. '[[Категория:Приказы с проблемами увольнения (запас или вовсе)]]'
	end
	local art = mw.ustring.lower( Args['статья'] )
	local artTxt = tools.db( dismissDb.article, art )
    if not artTxt then
        return tools.errorMsg ( 'увольнение', 'В параметре «статья» указан'
            .. ' неизвестный номер статьи')
    end
	artTxt = artTxt.txt
	local formula = Args['обоснование']
	local x
	if formula ~= '' then
		x = ' (' .. formula .. ')'
	else
		x = ''
	end

	return paramSet( {dir, art, formula}, 'увольнение', 'dismiss',
		table.concat( {dirTxt, artTxt}, ' ' ) .. x )
end

--[[------------------------------------------------------------]]-- Обоснование
-- Увольнение ( резерв/запас/отставка/вовсе/см.текст , статья , текст )
pp['Обоснование'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
--	local dismissDb = mw.loadData('Модуль:Виды увольнения')
	local formula, errMsg = paramCheck( 'обоснование',
		{ ['подразделение'] = true, ['место службы'] = true, ['дата'] = true },
		{ ['снять с работы'] = true, ['освободить от должности'] = true,
			['отстранить от работы'] = true, 	},
        { true,
--			['комментарий'] = true, ['сноска'] = true,
			}
        )
	if not formula then
		return tools.errorMsg( 'обоснование', errMsg )
	end

	return paramSet( formula, 'обоснование', 'dismiss' )
end

--[[---------------------------------------------------------]]-- В распоряжение
-- Увольнение ( резерв/запас/отставка/вовсе/см.текст , статья , текст )
pp['В распоряжение'] = function ( frame )
	Frame = frame
	Args =  frame:getParent().args
--	local dismissDb = mw.loadData('Модуль:Виды увольнения')
	local formula, errMsg = paramCheck( 'в распоряжение',
		{ ['подразделение'] = true, ['место службы'] = true, ['дата'] = true },
		{ ['отозвать'] = true, ['откомандировать'] = true },
        { true,
--			['комментарий'] = true, ['сноска'] = true,
			['место службы+'] = true,
			}
        )
	if not formula then
		return tools.errorMsg( 'в распоряжение', errMsg )
	end
	local x = Args['место службы+']
	if x then
		x = ' (' .. tools.segment( x ) .. ')'
	end

	return paramSet( { formula, Args['место службы+'] }, 'в распоряжение', 'dismiss',
		'в распоряжение ' .. formula .. ( x or '' ) )
end

--[[-------------------------------------------------------------]]-- (действия)

pp['Наградить'] = function ( frame )
	return doIt ( 'наградить',
		{ ['дата'] = true, ['награда'] = true, ['подразделение'] = true, ['место службы'] = true },
		frame )
end

pp['Лишить награды'] = function ( frame )
	return doIt ( 'лишить награды',
		{ ['награда'] = true, ['подразделение'] = true, ['место службы'] = true },
		frame )
end

pp['Присвоить звание'] = function ( frame )
	return doIt ( 'присвоить звание',
		{ ['звание'] = true, ['звание+'] = true, ['подразделение'] = true,
			['место службы'] = true },
		frame )
end

pp['Лишить звания'] = function ( frame )
	return doIt ( 'лишить звания',
		{ ['звание'] = true, ['подразделение'] = true, ['место службы'] = true },
		frame )
end

pp['Назначить'] = function ( frame )
	return doIt ( 'назначить',
		{ ['дата'] = true, ['подразделение'] = true, ['место службы'] = true },
		frame )
end

pp['Уволить'] = function ( frame )
	return doIt ( 'уволить',
		{ ['дата'] = true, ['подразделение'] = true, ['увольнение'] = true,
			['место службы'] = true },
		frame )
end

pp['Уволить и лишить звания'] = function ( frame )
	return doIt ( 'уволить и лишить звания',
		{ ['звание'] = true, ['дата'] = true, ['подразделение'] = true,
			['место службы'] = true, ['увольнение'] = true },
		frame )
end

pp['Освободить от должности'] = function ( frame )
	return doIt ( 'освободить от должности',
		{ ['дата'] = true, ['подразделение'] = true,
			['место службы'] = true, ['обоснование'] = true, },
		frame )
end

pp['Снять с работы'] = function ( frame )
	return doIt ( 'снять с работы',
		{ ['дата'] = true, ['подразделение'] = true,
			['место службы'] = true, ['обоснование'] = true, },
		frame )
end

pp['Отстранить'] = function ( frame )
	return doIt ( 'отстранить от работы',
		{ ['дата'] = true, ['подразделение'] = true,
			['место службы'] = true, ['обоснование'] = true, },
		frame )
end

pp['Откомандировать'] = function ( frame )
	return doIt ( 'откомандировать',
		{ ['дата'] = true, ['подразделение'] = true,
			['место службы'] = true, ['в распоряжение'] = true, },
		frame )
end

pp['Отозвать'] = function ( frame ) -- это то же самое, что и 'откомандировать'
	return doIt ( 'отозвать',
		{ ['дата'] = true, ['подразделение'] = true,
			['место службы'] = true, ['в распоряжение'] = true, },
		frame )
end

pp['Отменить'] = function ( frame )
	return doIt ( 'отменить', { }, frame )
end

pp['DEBUG'] = function ( frame )
	Doc = global.get('gDoc')
	Doc.debug = true
	global.set( 'gDoc', Doc )
end

return pp