Модуль: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] .. ' ' .. 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