Модуль:Ref

Материал из Указатель частей и соединений РККА 1941-1945
Перейти к:навигация, поиск

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

-- этот модуль может вызываться из фрейма (шаблон Сноска) или из других модулей.

local ref = {}

local global = mw.ext.luaglobal
local tools = require( 'Module:Tools' )
-- Можно сделать глобальными и устанавливать значения только в функциях, вызываемых из фрейма

local english = mw.getContentLanguage():getCode() == 'en'
local translation
local Alpha
if english then
	Alpha = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' }
	translation = {
		'Notes',
		'Notes of the original text are indicated by letter indices.',
	}
else
	Alpha = { 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ж', 'И', 'К', 'Л', 'М', 'Н', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ш', 'Ю', 'Я' }
	translation = {
		'Примечания',
		'Примечания оригинального текста обозначены буквенными индексами.',
	}
end


local REF_ORIG = 'o'
local REF_MY = 'm'


local uRefPart, uRefCount, uRef = {}, {}, {}
modRef = modRef or {}

local function refStyle( n, style )
	if style == REF_ORIG then
		if n <= #Alpha then
			return Alpha[n]
		end
		return 'А' .. Alpha[n-#Alpha]
	end
	return n
end

function ref.syntax( str )
	str = mw.text.trim( str )
	local dot = string.sub( str, -1 )
	if dot == '.' or dot == '!' or dot == '?' then
		dot = ''
	else
		dot = '.'
	end
	return mw.ustring.upper( mw.ustring.sub( str, 1, 1 ) ) .. mw.ustring.sub( str, 2, -1 ) .. dot
end


function ref.use( refer, pagemode )
	local referlist = mw.text.split( refer, '%s*$%s*' )
	local res = ''
	for _, u in ipairs( referlist ) do
		local reftype = string.sub( u, 1, 1 )
		if reftype ~= '-' or pagemode then
			if reftype == '!' or reftype == '-' then
				u = mw.text.trim( string.sub( u, 2, -1 ) )
				reftype = REF_ORIG
			else
				reftype = REF_MY
			end

			if not uRefCount[reftype] then
				uRefCount[reftype] = global.get( 'URefCount' .. reftype ) or 0
				uRef[reftype] = global.get( 'URef' .. reftype ) or {}
				uRefPart[reftype] = global.get( 'URefPart' .. reftype ) or 1
				modRef[reftype] = false
			end
			-- Нормализация примечаний: С большой буквы, в конце точка.
			u = mw.ustring.upper( mw.ustring.sub( u, 1, 1) ) .. mw.ustring.sub( u, 2, -1)
			if not string.find( '.!?>', string.sub( u, -1, -1 ), 1, true ) then
				u = u .. '.'
			end

			local refdata = uRef[reftype][u]
			if refdata then
				refdata[2] = refdata[2] + 1
			else
				uRefCount[reftype] = uRefCount[reftype] + 1
				refdata = { uRefCount[reftype], 1 }
				uRef[reftype][u] = refdata
			end
			modRef[reftype] = true
			u = string.gsub( u, '"', "''" )
			u = string.gsub( u, '%[%[[^|]+%|([^%]]+)%]%]', '%1' )
			u = string.gsub( u, '%b<>', '' )
			res = res .. '[[#milreftext-' .. reftype .. '-' .. uRefPart[reftype] .. '-' .. refdata[1]
				.. '|<span id="milrefref-' .. reftype .. '-' .. uRefPart[reftype] .. '-' .. refdata[1] .. '-' .. refdata[2]
				.. '" class="mil-ref-' .. reftype .. '" title="' .. u ..'">'
				.. refStyle( refdata[1], reftype ) .. '</span>]]'
		elseif reftype == '-' then
			ref.coverRef = mw.text.trim( string.sub( u, 2, -1 ) )
		end
	end
	return res
end

function ref.refStart( reftype )
	if not reftype then
		return ref.refStart( REF_ORIG ), ref.refStart( REF_MY )
	end
	if not uRefCount[reftype] then
		uRefCount[reftype] = global.get( 'URefCount' .. reftype ) or 0
		uRef[reftype] = global.get( 'URef' .. reftype ) or {}
		uRefPart[reftype] = global.get( 'URefPart' .. reftype ) or 1
		modRef[reftype] = false
	end
end

function ref.dump( reftype )
	if not uRefCount[reftype] then
		uRefCount[reftype] = global.get( 'URefCount' .. reftype ) or 0
		uRef[reftype] = global.get( 'URef' .. reftype ) or {}
		uRefPart[reftype] = global.get( 'URefPart' .. reftype ) or 1
		modRef[reftype] = false
	end
	if uRefCount[reftype] == 0 then
		return nil
	end
	local refArray = {}
	for u, v in pairs( uRef[reftype] ) do
		refArray[v[1]] = { v[2], u }
	end
	for i, u in ipairs( refArray ) do
		refArray[i] = '<p class="mil-refrow"><span id="milreftext-' .. reftype .. '-' .. uRefPart[reftype] .. '-' .. i
			.. '" class="mil-ref-' .. reftype .. '">' .. refStyle( i, reftype ) .. '</span> '
		for j = 1, u[1] do
			refArray[i] = refArray[i] .. '[[#milrefref-' .. reftype .. '-' .. uRefPart[reftype] .. '-' .. i .. '-' .. j
				.. '|<i class="fas fa-link "></i>]] '
		end
		refArray[i] = refArray[i] .. '&nbsp; ' .. u[2] .. '</p>'
	end
	uRefCount[reftype] = nil
	uRef[reftype] = nil
	uRefPart[reftype] = uRefPart[reftype] + 1
	modRef[reftype] = true
	return table.concat( refArray, '\n' )
end

function ref.refReturn( text )
	if modRef[REF_ORIG] then
		global.set( 'URef' .. REF_ORIG, uRef[REF_ORIG] )
		global.set( 'URefCount' .. REF_ORIG, uRefCount[REF_ORIG] )
		global.set( 'URefPart' .. REF_ORIG, uRefPart[REF_ORIG] )
		modRef[REF_ORIG] = nil
	end
	if modRef[REF_MY] then
		global.set( 'URef' .. REF_MY, uRef[REF_MY] )
		global.set( 'URefCount' .. REF_MY, uRefCount[REF_MY] )
		global.set( 'URefPart' .. REF_MY, uRefPart[REF_MY] )
		modRef[REF_MY] = nil
	end
	return text
end

function ref.refOut( headerClass )
	headerClass = headerClass or 'h3'
	ref.refReturn()
	local out = {}
	if ( uRefCount[REF_ORIG] or 0 ) ~= 0 or ( uRefCount[REF_MY] or 0 ) ~= 0 then
		table.insert( out, '<p class="' .. headerClass .. '">' .. translation[1] .. '</p><div class="small">' )
		if ( uRefCount[REF_ORIG] or 0 ) ~= 0 then
			table.insert( out, '<p class="text-muted">' .. translation[2] .. '</p>' )
			table.insert( out,  ref.dump( REF_ORIG ) )
		end
		if uRefCount[REF_MY] then
			table.insert( out,  ref.dump( REF_MY ) )
		end
		table.insert( out,  '</div>' )
	end
	return table.concat( out )
end

function ref.Out( frame )
	ref.refStart()
	return ref.refReturn( ref.refOut () )
end

function ref.Refer( frame )
	local args = tools.checkargs( frame:getParent().args, {
			true,
		} )
--	refStart()
--	return p._refer( args[1], frame )
	return ref.refReturn( ref.use( args[1] ) )
end
ref['Сноска'] = ref.Refer

return ref