Модуль:Report
Материал из Указатель частей и соединений РККА 1941-1945
Для документации этого модуля может быть создана страница Модуль:Report/doc
local report = {}
local ref = require( 'Module:Ref' )
local lexer = require( 'Module:Lexer' )
local global = mw.ext.luaglobal
local redata
local formation
local knownBrackets
local knownBracketsSuperOut
local translation
local english = mw.getContentLanguage():getCode() == 'en'
if english then
redata = mw.loadData( 'Module:Redata.en' )
translation = {
'Separate',
'Guards',
'“',
'”',
'Only Headquarter',
"Field Forces",
"Military districts and inactive fronts",
'Military District$',
'inactive forces',
"Air defense forces on the territory of military districts and inactive fronts",
'Front − air defense troops$',
'inactive front',
"Air Defense Forces of the Country",
"Air defense forces that covered the objects of the active army",
'District − air defense troops$',
'Module:Formation.en',
'Military District %(I+ formation%)$',
}
knownBrackets = {
['Pol.'] = 'Pol.',
['Fr.'] = 'Fr.',
['Hung.'] = 'Hung.',
['Czech.'] = 'Czech.',
['Yug.'] = 'Yug.',
['Rom.'] = 'Rom.',
['Bulg.'] = 'Bulg.',
['Mong.'] = 'Mong.',
['I'] = 1,
['II'] = 2,
['III'] = 3,
['IV'] = 4,
['V'] = 5,
['VI'] = 6,
['I formation'] = 1,
['II formation'] = 2,
['III formation'] = 3,
['IV formation'] = 4,
['V formation'] = 5,
['VI formation'] = 6,
}
knownBracketsSuperOut = {
'I formation',
'II formation',
'III formation',
'IV formation',
'V formation',
'VI formation',
}
else
redata = mw.loadData( 'Module:Redata' )
translation = {
'отд%.',
'гв%.',
'«',
'»',
'Управление без войск',
'Действующая армия',
'Военные округа и недействующие фронты',
'военный округ$',
'недействующие войска',
'Войска ПВО на территории военных округов и недействующих фронтов',
'фронт — войска ПВО$',
'недействующий фронт',
'Войска ПВО территории страны',
'Войска ПВО, прикрывавшие объекты действующей армии',
'округ — войска ПВО$',
'Module:Formation',
'военный округ %(I+ формирования%)$',
}
knownBrackets = {
['Войско Польское'] = 'Войско Польское',
['ВП'] = 'Войско Польское',
['фр.'] = 'фр.',
['венг.'] = 'венг.',
['чех.'] = 'чех.',
['югосл.'] = 'югосл.',
['рум.'] = 'рум.',
['болг.'] = 'болг.',
['монг.'] = 'монг.',
['I'] = 1,
['II'] = 2,
['III'] = 3,
['IV'] = 4,
['V'] = 5,
['VI'] = 6,
['I формирования'] = 1,
['II формирования'] = 2,
['III формирования'] = 3,
['IV формирования'] = 4,
['V формирования'] = 5,
['VI формирования'] = 6,
}
knownBracketsSuperOut = {
'I формирования',
'II формирования',
'III формирования',
'IV формирования',
'V формирования',
'VI формирования',
}
end
report.knownBrackets = knownBrackets
local buffer = {}
local bufferCommon, bufferCommonN, bufferCommonAdd, bufferCommonForm, bufferCommonStruct, bufferCommonHq, bufferCommonGene
report.space = ' '
report.pageMode = true
if english then
function report.simplecat( str ) -- использует очищенное от скобок наименование
local a = ( string.match( str, '^(.+)( “.+”)$' ) ) or str
local b = string.match( a, 'Guards (.+)$' )
if b then
if string.find( ' ' .. b, ' Mortar' ) then
a = 'Guards ' .. b
else
a = b
end
else
b = string.match( a, 'Separate (.+)$' )
if b then
a = b
else
a = ( string.match( a, '^%d[^ ]* (.+)$' ) ) or a
end
end
return a
end
else
function report.simplecat( str ) -- использует очищенное от скобок наименование
local a = ( string.match( str, '^(.+)( «.+»)$' ) ) or str
local b = mw.ustring.match( a, '[гГ]в%. (.+)$' )
if b then
if string.find( ' ' .. b, ' минометн' ) then
a = 'гв. ' .. b
else
a = b
end
else
b = string.match( a, '[оО]тд%. (.+)$' )
if b then
a = b
else
a = ( string.match( a, '^%d[^ ]* (.+)$' ) ) or a
end
end
return a
end
end
function report.fuller( str, badAbbr )
badAbbr = badAbbr or {}
if badAbbr[str] or redata.Full[str] then
return badAbbr[str] or redata.Full[str]
end
local num, a = string.match( str, '^(%d[^ ]* )(.+)$' )
if num then
local gv, otd, otdInc
a, gv = string.gsub( a, 'гв. ', '' )
if gv == 1 then
gv = 'гв. '
else
gv = ''
end
a, otd = string.gsub( a, 'отд. ', '' )
if otd == 1 then
otd = 'отд. '
else
otd = ''
end
a = badAbbr[a] or redata.Full[a]
if a then
a, otdInc = string.gsub( a, 'отд. ', '' )
if otdInc == 1 then
otd = 'отд. '
end
return num .. otd .. gv .. a
end
else
num, a = string.match( str, '^([^ ]* )(.+)$' )
if badAbbr[a] or redata.Full[a] then
return num .. ( badAbbr[a] or redata.Full[a] )
end
end
return str
end
--function report.bigfuller( str, badAbbr )
-- local stored = {}
-- local n
-- repeat
-- str, n = string.gsub( str, ' %(([^()]+)%)', function ( u )
-- if knownBracketsBig[u] then
-- table.insert( stored, knownBracketsBig[u] )
-- return '&' .. string.char( 96 + #stored )
-- else
-- local parts = mw.text.split( mw.text.trim( u ), '%s*,%s*' )
-- for i, part in ipairs( parts ) do
-- local body, ending = string.match( part, '^([^&]+)(.*)$' )
-- parts[i] = lexer.declension( report.fuller( body ), 1, true ) .. ending
-- end
-- table.insert( stored, table.concat( parts, ', ' ) )
-- end
-- return '&' .. string.char( 96 + #stored )
-- end )
-- until n == 0
-- local body, ending = string.match( str, '^([^&]+)(.*)$' )
-- str = report.fuller( body, badAbbr ) .. ending
-- repeat
-- str, n = string.gsub( str, '&(.)', function ( u )
-- return ' (' .. stored[string.byte( u ) - 96] .. ')'
-- end )
-- until n == 0
-- return str
--end
local function parseList( list, collection )
local stored = {}
list = string.gsub( list, '%b()', function( a )
table.insert( stored, a )
return '&' .. string.char( 96 + #stored )
end )
local parts = mw.text.split( list, '%s*,%s*' )
for i, part in ipairs( parts ) do
local lexxx
part = report.bigfuller( ( string.gsub( part, '&(.)', function ( u )
return stored[string.byte( u ) - 96]
end ) ) )
parts[i], lexxx = lexer.declension( part, 1, true ) -- получаем склоненное+ключ, либо несклоненное+nil
if collection then
if not lexxx then
part = ''
end
table.insert( collection, part )
end
end
return parts -- возвращаем список текстов (склоняемых и несклоняемых), а в collection — список склоняемых юнитов (с пустыми текставми вместо несклоняемых)
end
function report.bigfuller( str, badAbbr, parentsCollection )
local shorted, parent, generation, foreign
local body, overname = string.match( str, '^(.+) %[(.+)%]$' )
body = body or str
repeat
local el
shorted, el = string.match( body, '^(.-)%s+(%b())$' )
if shorted then
body = shorted
el = mw.text.trim( string.sub( el, 2, -2 ) )
local u = knownBrackets[el]
if u then
if type( u ) == 'number' then
generation = knownBracketsSuperOut[u]
else
foreign = u
end
else
parent = el
end
end
until not shorted
if parent then
local parts = parseList( parent, parentsCollection )
parent = ' (' .. string.gsub( table.concat( parts, ', ' ), ' формирования%)', '%)' ) .. ')'
end
if overname then
local overList = {}
local parts = parseList( overname, overList )
for i, overUnit in ipairs( overList ) do
if overUnit ~= '' then
global.add( 'UNIT-IN-TEXT', overUnit )
parts[i] = '<span class=unit-in-text data-unit="' .. overUnit .. '">[[' .. overUnit ..'|' .. parts[i] .. ']]</span>'
end
end
overname = table.concat( parts, ', ' )
end
if foreign then
foreign = ' (' .. foreign .. ')'
end
if generation then
generation = ' (' .. generation .. ')'
end
body = report.fuller( body, badAbbr )
return body .. ( foreign or '' ) .. ( parent or '' ) .. ( generation or '' ), body .. ( generation or '' ), overname
end
--function report.bigfuller( str, badAbbr, classfunc )
-- classfunc = classfunc or function () return '' end
-- local body = str
-- local shorted, parent, showParent, generation, foreign
-- repeat
-- local el
-- shorted, el = string.match( body, '^(.-)%s+(%b())$' )
-- if shorted then
-- body = shorted
-- el = mw.text.trim( string.sub( el, 2, -2 ) )
-- local u = knownBrackets[el]
-- if u then
-- if type( u ) == 'number' then
-- generation = knownBracketsSuperOut[u]
-- else
-- foreign = u
-- end
-- else
-- parent = el
-- end
-- end
-- until not shorted
-- if parent then
-- local stored = {}
-- local showed = {}
-- parent = string.gsub( parent, '%b()', function( a )
-- table.insert( stored, a )
-- return '&' .. string.char( 96 + #stored )
-- end )
-- local parts = mw.text.split( parent, '%s*,%s*' )
-- for i, part in ipairs( parts ) do
-- local lexxx
-- part = string.gsub( part, '&(.)', function ( u )
-- return stored[string.byte( u ) - 96]
-- end )
-- part = report.bigfuller( part )
-- parts[i], lexxx = string.gsub( lexer.declension( part, 1, true ), ' формирования%)', '%)' )
-- if lexxx then
-- table.insert( showed, '<span class="unit-top ' .. classfunc( part ) .. '">[[' .. part .. '|' .. parts[i] .. ']]</span>' )
-- else
-- table.insert( showed, part )
-- end
-- end
-- parent = ' (' .. table.concat( parts, ', ' ) .. ')'
-- showParent = ' (' .. table.concat( showed, ', ' ) .. ')'
-- end
-- if foreign then
-- foreign = ' (' .. foreign .. ')'
-- end
-- if generation then
-- generation = ' (' .. generation .. ')'
-- end
-- local a = report.fuller( body, badAbbr ) .. ( foreign or '' )
-- local u = a .. ( parent or '' ) .. ( generation or '' )
-- local spanu = classfunc( u )
-- if spanu ~= '' then
-- a = '<span class="' .. spanu .. '">' .. a .. '</span>'
-- end
-- return u, a, showParent, generation
--end
function report.shorter( str, plural )
-- отделяем хвосты
local brackets, quotes, numb, name, otd, gv
local a, b
local abbr
local function acheck( u, plural )
if english then
if not plural then
return u
end
local body2, top = string.match( u, '^(.-) of( .+)$' )
if not body2 then
body2, top = u, ''
end
local words = mw.text.split( body2, ' ' )
local main, plw
for i = #words, 1, -1 do
plw = redata.Plurals[words[i]]
if plw then
main = i
break
end
end
if not main then
return nil
end
local pre, post
if main ~= 1 then
pre = table.concat( words, ' ', 1, main-1 ) .. ' ' .. plw
else
pre = plw
end
if main ~= #words then
post = ' ' .. table.concat( words, ' ', main+1 )
else
post = ''
end
return pre .. post .. top
else
local descr = redata.Descr[u]
if not descr then
return nil
end
if plural then
return descr[2] or descr[1]
end
return descr[1]
end
end
a, brackets = string.match( str, '^(.-) %((.+)%)$' )
local owngene
if not a then
a = str
brackets = ''
else
local bracketsA = mw.text.split( brackets, ') (', true )
brackets = ''
-- for i = 1, #bracketsA do
-- if knownBrackets[bracketsA[i]] then
-- brackets = brackets .. ' (' .. bracketsA[i] .. ')'
-- end
-- end
for _, bra in ipairs( bracketsA ) do
local known = knownBrackets[bra]
if known then
if type( known ) == 'string' then
if report.gene then
if known ~= report.gene then
error( 'Межнациональная рознь: ' .. report.gene .. ' содержит ' .. known )
else
owngene = known
end
else
owngene = known
brackets = brackets .. ' (' .. known .. ')'
end
else
-- brackets = brackets .. ' (' .. bra .. ')'
end
end
end
end
if report.gene and not owngene then
brackets = brackets .. ' (РККА)'
else
report.gene = owngene
end
b, quotes = string.match( a, '^(.+)( ' .. translation[3] .. '.+' .. translation[4] .. ')$' )
if b then
a = b
else
quotes = ''
end
numb, b = string.match( a, '^(%d+%-?[абв]?) (.+)$' )
if numb then
numb = numb .. report.space
a = b
end
-- ИИИ отд. гв. ТТТ: (отд. ТТТ), (ТТТ)
-- ИИИ отд. ТТТ: (отд. ТТТ), (ТТТ)
-- ИИИ гв. ТТТ: (ТТТ)
-- ИИИ ТТТ: (ИИИ ТТТ), (ТТТ)
-- name, otd, gv, b = string.match( a, '^(.*)(отд%. )(гв%. )(.+)$' )
name, otd, gv, b = string.match( a, '^(.*)(' .. translation[1] .. ' )(' .. translation[2] .. ' )(.+)$' )
if name then
abbr = acheck( otd .. b, plural )
if abbr then
return ( numb or '' ) .. name .. gv .. abbr .. quotes .. brackets
end
abbr = acheck( b, plural )
if abbr then
return ( numb or '' ) .. name .. otd .. gv .. abbr .. quotes .. brackets
end
return str
end
name, otd, b = string.match( a, '^(.*)(' .. translation[1] .. ' )(.+)$' )
if name then
abbr = acheck( otd .. b, plural )
if abbr then
return ( numb or '' ) .. name .. abbr .. quotes .. brackets
end
abbr = acheck( b, plural )
if abbr then
return ( numb or '' ) .. name .. otd .. abbr .. quotes .. brackets
end
return str
end
name, gv, b = string.match( a, '^(.*)(' .. translation[2] .. ' )(.+)$' )
if name then
abbr = acheck( b, plural )
if abbr then
return ( numb or '' ) .. name .. gv .. abbr .. quotes .. brackets
end
return str
end
abbr = acheck( a, plural )
if abbr then
return ( numb or '' ) .. abbr .. quotes .. brackets
end
name, b = string.match( a, '^([^ ]+ )(.+)$' )
if name then
abbr = acheck( b, plural )
if abbr then
return ( numb or '' ) .. name .. abbr .. quotes .. brackets
end
end
return str
end
function report.outPart( showMode, link, unit, addendum, reference, inFormation, hq )
-- showMode = false/nil не показывать, 1 кратко, 2 полностью; string — текст, показываемый вместо названия юнита (для буферизации)
-- link = true — превращать в ссылку (игнор при mode=false/nil)
local res = {}
if link and showMode then
table.insert( res, '[[' .. unit )
if showMode == 1 then
table.insert( res, '|' .. report.shorter( unit ) )
elseif showMode == 2 then
local woBrackets = string.gsub( unit, ' %b()', function( a )
if type( knownBrackets[a] ) ~= 'string' then
return ''
end
end )
table.insert( res, '|' .. woBrackets )
elseif type( showMode ) == 'string' then
table.insert( res, '|' .. showMode )
end
table.insert( res, ']]' )
elseif showMode == 2 then
local woBrackets = string.gsub( unit, ' %b()', function( a )
if type( knownBrackets[a] ) ~= 'string' then
return ''
end
end )
table.insert( res, woBrackets )
elseif showMode == 1 then
table.insert( res, report.shorter( unit ) )
end
if ( reference or '' ) ~= '' then
table.insert( res, ref.use( reference, report.pageMode ) )
end
if type( showMode ) ~= 'string' then
if ( hq or '' ) ~= '' then
table.insert( res, ' (<span title="' .. translation[5] .. '">∅</span>)' )
end
if ( addendum or '' ) ~= '' then
table.insert( res, ' <i>(' .. addendum .. ')</i>' )
end
if ( inFormation or '' ) ~= '' then
formation = formation or mw.loadData( translation[16] )
table.insert( res, ' — <i>' .. formation.FUP[tonumber( inFormation )] .. '</i>')
end
end
return table.concat( res )
end
function report.outEl( tab, n, showMode, link, compact )
local res = ''
local unit = tab['id'..n]
if ( unit or '' ) ~= '' then
if unit == translation[6] then
return nil
elseif unit == translation[7] then
if string.match( tab['id'..(n -1)], translation[8] ) or string.match( tab['id'..(n -1)], translation[17] ) then
return nil
else
return '<i>(' .. translation[9] .. ')</i>'
end
elseif unit == translation[10] then
if string.match( tab['id'..(n -1)], translation[11] ) then
res = '<i>(' .. translation[12] .. ')</i> / '
end
unit = translation[13]
elseif unit == translation[14] then
if string.match( tab['id'..(n -1)], translation[15] ) then
res = '<i>(' .. translation[6] .. ')</i> / '
end
unit = translation[13]
end
if compact then
return report.toBuffer( tab, n )
end
res = res .. report.outPart( showMode, link, unit, tab['add'..n], tab['ref'..n], tab['form'..n], tab['hq'..n] )
if ( tab['s_id'..n] or '' ) ~= '' then
res = res .. ' [<i></i>' .. report.outPart( showMode, true, tab['s_id'..n], tab['s_add'..n], tab['s_ref'..n], '', '' ) .. ']'
end
return res
end
end
function report.toBuffer( tab, n )
local unit = tab['id'..n]
unit = string.match( unit, '^(.-) %(.+%)$' ) or unit
local x, u = string.match( unit, '^([^ ]+) (.+)$' )
local res
if not x then
x = unit
u = ''
end
-- assert( x, unit )
if bufferCommon and
( u ~= bufferCommon or tab['add'..n] ~= bufferCommonAdd
or tab['form'..n] ~= bufferCommonForm or tab['s_id'..n] ~= bufferCommonStruct
or bufferCommonGene ~= report.gene or tab['hq'..n] ~= bufferCommonHq ) then
res = report.popBuffer()
end
if not bufferCommon then
-- bufferTab = tab
bufferCommon = u
bufferCommonAdd = tab['add'..n]
bufferCommonForm = tab['form'..n]
bufferCommonStruct = tab['s_id'..n]
bufferCommonHq = tab['hq'..n]
bufferCommonN = n
bufferCommonGene = report.gene
end
table.insert( buffer, { n, x, tab } )
return res
end
function report.popBuffer()
if bufferCommon then
local savedGene = report.gene
report.gene = bufferCommonGene
if #buffer == 1 then
local n, utab = buffer[1][1], buffer[1][3]
buffer = {}
bufferCommon = nil
local res = report.outEl( utab, n, 1, true )
report.gene = savedGene
return res
end
local res = {}
for _, el in ipairs( buffer ) do
local n, unumb, utab = el[1], el[2], el[3]
table.insert( res, report.outPart( unumb, true, utab['id'..n], bufferCommonAdd, utab['ref'..n], bufferCommonForm, bufferCommonHq ) )
-- в реальности add, form, hq тут игнорируются
end
res = { table.concat( res, ', ' ) .. report.space .. report.shorter( bufferCommon, true ) }
if ( bufferCommonHq or '' ) ~= '' then
table.insert( res, ' (<span title="Управление без войск">∅</span>)' )
end
if ( bufferCommonAdd or '' ) ~= '' then
table.insert( res, '<i>(' .. bufferCommonAdd .. ')</i>' )
end
if ( bufferCommonForm or '' ) ~= '' then
formation = formation or mw.loadData( translation[16] )
table.insert( res, '— <i>' .. formation.FUP[tonumber( bufferCommonForm )] .. '</i>' )
end
local btab = buffer[1][3]
if ( bufferCommonStruct or '' ) ~= '' then
table.insert( res, '[<i></i>' .. report.outPart( 1, true, bufferCommonStruct, btab['s_add'..bufferCommonN], btab['s_ref'..bufferCommonN], '' ) .. ']' )
end
buffer = {}
bufferCommon = nil
report.gene = savedGene
return table.concat( res, ' ' )
else
return nil
end
end
function report.printDate( str )
if ( str or '' ) ~= '' then
return '<span class=date-field>'
.. string.sub( str, 9, 10 ) .. '.' .. string.sub( str, 6, 7 ) .. '.'
.. string.sub( str, 1, 4 ) .. '</span>'
end
return '<span class=date-field> </span>'
end
function report.printDateLink( page, bookpage, text )
local basepage, date, part
if ( bookpage or '' ) == '' then
bookpage = ''
else
bookpage = '#p' .. bookpage
end
if page then
basepage, date, part = string.match( page, '^(.+ (%d%d%.%d%d%.%d%d%d%d))/(%d)$' )
assert( basepage )
date = '[[' .. basepage .. bookpage .. '|' .. ( text or date ) .. ']]'
else
date = ' '
part = ''
end
return '<span class="oobdate date-field" data-part="' .. part .. '">'
.. date .. '</span>'
end
function report.printDateWithLink( row )
local basepage, date, part, page, bookpage
if ( row.bookpage or '' ) == '' then
bookpage = ''
else
bookpage = '#p' .. row.bookpage
end
page = row.page
if page then
basepage, part = string.match( page, '^(.+)/(%d)$' )
assert( basepage )
if english then
date = row.date
else
date = string.sub( row.date, 9, 10 ) .. '.' .. string.sub( row.date, 6, 7 ) .. '.'
.. string.sub( row.date, 1, 4 )
end
date = '[[' .. basepage .. bookpage .. '|' .. date .. ']]'
else
date = ' '
part = ''
end
return '<span class="oobdate date-field" data-part="' .. part .. '">'
.. date .. '</span>'
end
return report