Модуль:Enumeration: различия между версиями
Материал из Указатель частей и соединений РККА 1941-1945
Строк (обсуждение | вклад) |
WikiSysop (обсуждение | вклад) |
||
(не показано 26 промежуточных версий 2 участников) | |||
Строка 5: | Строка 5: | ||
local report = require( 'Module:Report' ) | local report = require( 'Module:Report' ) | ||
local lexer = require( 'Module:Lexer' ) | local lexer = require( 'Module:Lexer' ) | ||
+ | local dataOut = mw.loadData( 'Module:DataOut' ) | ||
local cargo = mw.ext.cargo | local cargo = mw.ext.cargo | ||
Строка 10: | Строка 11: | ||
local TYPE_SUBDIV = '3' | local TYPE_SUBDIV = '3' | ||
local TYPE_SUBCORP = '5' | local TYPE_SUBCORP = '5' | ||
+ | |||
+ | local enumHeader = [[ | ||
+ | <div class=enum-table-header> | ||
+ | <div class=enum-unitrow-wrapper> | ||
+ | <div class=enum-unit-wrapper>Объединение, соединение, часть</div> | ||
+ | <div class=enum-create-wrapper>Сведения о создании</div> | ||
+ | <div class=enum-time-wrapper>В действующей армии</div> | ||
+ | <div class=enum-death-wrapper>Дальнейшая судьба</div> | ||
+ | </div> | ||
+ | <div class=enum-end> </div> | ||
+ | </div> | ||
+ | ]] | ||
Строка 68: | Строка 81: | ||
local out = {} | local out = {} | ||
+ | |||
+ | -- можно и для остальных так проверять первый заголовок | ||
+ | if not global.get( 'enum-page' ) then | ||
+ | table.insert( out, frame:callParserFunction{ name = '#seo', args = { '', | ||
+ | description = 'Перечень № ' .. eN .. '. ' .. ( toc.short or 'Состав действуюшей армии в период Великой отечественной войны' ) .. '.', | ||
+ | keywords = 'перечни, действующая армия, Великая Отечественная война, боевой состав', | ||
+ | } | ||
+ | } ) | ||
+ | if pager then | ||
+ | table.insert( out, '[[Category:Перечни (формирование БД)|' | ||
+ | .. string.sub( '0' .. eN, -2, -1) .. pager .. ']]<div class=show-disambig>' ) | ||
+ | else | ||
+ | table.insert( out, '[[Category:Перечни|' | ||
+ | .. string.sub( '0' .. eN, -2, -1).. ']]<div>' ) | ||
+ | end | ||
+ | end | ||
+ | |||
if not myDescr.up then | if not myDescr.up then | ||
table.insert( out, '<div class=enum-toc><div class=enum-toc-header>Оглавление</div>' ) | table.insert( out, '<div class=enum-toc><div class=enum-toc-header>Оглавление</div>' ) | ||
table.insert( out, require( 'Module:EnumTOC' ).makeTOC( eN ) ) | table.insert( out, require( 'Module:EnumTOC' ).makeTOC( eN ) ) | ||
table.insert( out, '</div>' ) | table.insert( out, '</div>' ) | ||
+ | table.insert( out, enumHeader ) | ||
end | end | ||
Строка 83: | Строка 114: | ||
local label = myDescr.up | local label = myDescr.up | ||
− | + | local outPos = #out+1 | |
repeat | repeat | ||
local descr = toc[label] | local descr = toc[label] | ||
Строка 89: | Строка 120: | ||
if descr.left then | if descr.left then | ||
table.insert( outline, '<span class=enum-left-link>[[' .. enumLink( eN, toc, descr.left ) | table.insert( outline, '<span class=enum-left-link>[[' .. enumLink( eN, toc, descr.left ) | ||
− | .. '|<i class=" | + | .. '|<i class="far fa-caret-square-left></i>]] </span>' ) |
end | end | ||
table.insert( outline, '[[' .. enumLink( eN, toc, label ) .. '|' ) | table.insert( outline, '[[' .. enumLink( eN, toc, label ) .. '|' ) | ||
Строка 98: | Строка 129: | ||
if descr.right then | if descr.right then | ||
table.insert( outline, '<span class=enum-right-link> [[' .. enumLink( eN, toc, descr.right ) | table.insert( outline, '<span class=enum-right-link> [[' .. enumLink( eN, toc, descr.right ) | ||
− | .. '|<i class=" | + | .. '|<i class="far fa-caret-square-right></i>]]</span>' ) |
end | end | ||
table.insert( outline, '</div>\n' ) | table.insert( outline, '</div>\n' ) | ||
− | table.insert( out, | + | table.insert( out, outPos, table.concat( outline ) ) |
label = descr.up | label = descr.up | ||
until not label | until not label | ||
− | table.insert( out, | + | table.insert( out, outPos, '<div class=enum-path>' ) |
table.insert( out, '</div>' ) | table.insert( out, '</div>' ) | ||
-- GLOBAL_enum = eN | -- GLOBAL_enum = eN | ||
Строка 116: | Строка 147: | ||
if myDescr.left then | if myDescr.left then | ||
table.insert( out, '<span class=enum-path-left-link>[[' .. enumLink( eN, toc, myDescr.left ) | table.insert( out, '<span class=enum-path-left-link>[[' .. enumLink( eN, toc, myDescr.left ) | ||
− | .. '|<i class=" | + | .. '|<i class="far fa-caret-square-left></i>]] </span>' ) |
end | end | ||
if myDescr[1] ~= '' then | if myDescr[1] ~= '' then | ||
Строка 124: | Строка 155: | ||
if myDescr.right then | if myDescr.right then | ||
table.insert( out, '<span class=enum-path-right-link> [[' .. enumLink( eN, toc, myDescr.right ) | table.insert( out, '<span class=enum-path-right-link> [[' .. enumLink( eN, toc, myDescr.right ) | ||
− | .. '|<i class=" | + | .. '|<i class="far fa-caret-square-right></i>]]</span>' ) |
end | end | ||
table.insert( out, '</div>' ) | table.insert( out, '</div>' ) | ||
Строка 140: | Строка 171: | ||
local mLength = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } | local mLength = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } | ||
− | local function | + | local function parseDate( txt ) |
if txt == '' then | if txt == '' then | ||
− | return ' | + | return '' |
end | end | ||
local res = mw.text.split( txt, '.', true ) | local res = mw.text.split( txt, '.', true ) | ||
Строка 157: | Строка 188: | ||
m = tonumber( m ) | m = tonumber( m ) | ||
assert( m >= 1 and m <= 12, 'недопустимый номер месяца' ) | assert( m >= 1 and m <= 12, 'недопустимый номер месяца' ) | ||
− | res = string.sub( '0' .. m, -2, -1 ) | + | res = res .. '-' .. string.sub( '0' .. m, -2, -1 ) |
if d then | if d then | ||
d = tonumber( d ) | d = tonumber( d ) | ||
assert( d >= 1 and d <= mLength[m] and ( m ~= 2 or d ~= 29 or y % 4 == 0 ), 'недопустимое число в месяце' ) | assert( d >= 1 and d <= mLength[m] and ( m ~= 2 or d ~= 29 or y % 4 == 0 ), 'недопустимое число в месяце' ) | ||
− | res = string.sub( '0' .. d, -2, -1 ) | + | res = res .. '-' .. string.sub( '0' .. d, -2, -1 ) |
end | end | ||
end | end | ||
− | return res | + | return res |
end | end | ||
Строка 171: | Строка 202: | ||
local dates = mw.text.split( str, '%s*%-%s*' ) | local dates = mw.text.split( str, '%s*%-%s*' ) | ||
assert( #dates == 2, 'Нет диапазона дат' ) | assert( #dates == 2, 'Нет диапазона дат' ) | ||
− | local start | + | local start = parseDate( dates[1] ) |
− | assert( start, 'Плохая дата ' .. dates[1] | + | assert( start, 'Плохая дата ' .. dates[1] ) |
− | local finish | + | local finish = parseDate( dates[2] ) |
− | assert( finish, 'Плохая дата ' .. dates[2] | + | assert( finish, 'Плохая дата ' .. dates[2] ) |
if start == '' or finish == '' then | if start == '' or finish == '' then | ||
assert( not hard, 'Должны быть заданы обе границы интервала дат' ) | assert( not hard, 'Должны быть заданы обе границы интервала дат' ) | ||
else | else | ||
− | assert( | + | assert( start <= finish, 'Извращенный диапазон дат' ) |
end | end | ||
return start, finish | return start, finish | ||
Строка 238: | Строка 269: | ||
end | end | ||
− | local function | + | local function markHL( unit, str ) |
− | |||
if lowNameHL[mw.ustring.lower( unit )] then | if lowNameHL[mw.ustring.lower( unit )] then | ||
− | + | return '<span class=enum-highlight>' .. ( str or unit ) .. '</span>' | |
end | end | ||
− | return | + | return str or unit |
end | end | ||
+ | local function unitLink( unit, text, parents ) | ||
+ | if text or not parents then | ||
+ | return '[[' .. unit .. '|' .. markHL( unit, text ) .. ']]' | ||
+ | end | ||
+ | local body = unit | ||
+ | local shorted, parent, 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 ) ) | ||
+ | if dataOut.generation[el] then | ||
+ | generation = ' (' .. el .. ')' | ||
+ | elseif dataOut.foreigner[el] then | ||
+ | foreign = ' (' .. el .. ')' | ||
+ | else | ||
+ | parent = el | ||
+ | end | ||
+ | end | ||
+ | until not shorted | ||
+ | |||
+ | if parent then | ||
+ | local stored = {} | ||
+ | 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 | ||
+ | part = --[[report.bigfuller( ( ]] string.gsub( part, '&(.)', function ( u ) | ||
+ | return stored[string.byte( u ) - 96] | ||
+ | end ) --[[ ) ) ]] | ||
+ | if ( parents[i].unit or '' ) ~= '' then | ||
+ | parts[i] = '[[' .. parents[i].unit .. '|' .. markHL( parents[i].unit, part ) .. ']]' | ||
+ | else | ||
+ | parts[i] = part | ||
+ | end | ||
+ | end | ||
+ | -- parent = ' (' .. string.gsub( table.concat( parts, ', ' ), ' формирования%)', '%)' ) .. ')' | ||
+ | parent = ' (' .. table.concat( parts, ', ' ) .. ')' | ||
+ | end | ||
+ | |||
+ | return '[[' .. unit .. '|' .. markHL( unit, body .. ( foreign or '' ) ) .. ']]' .. ( parent or '' ) .. ( generation or '' ) | ||
+ | end | ||
+ | |||
+ | -- local function dmy( arr, field ) | ||
+ | -- local d=arr[field] | ||
+ | -- if string.sub( d, 5, 5 ) == '-' then -- данные из базы | ||
+ | -- d = tools.dmy( d ) | ||
+ | -- local prec = arr[field .. '__precision'] | ||
+ | -- if prec == 2 then | ||
+ | -- d = string.sub( d, 4, 10 ) | ||
+ | -- elseif prec == 3 then | ||
+ | -- d = string.sub( d, 7, 10 ) | ||
+ | -- end | ||
+ | -- end | ||
+ | -- return string.rep( ' ', #d-10 ) .. d | ||
+ | -- end | ||
local function dmy( arr, field ) | local function dmy( arr, field ) | ||
local d=arr[field] | local d=arr[field] | ||
− | + | d = tools.dmy( d ) | |
− | + | local prec = arr[field .. '__precision'] -- если из базы | |
− | + | if prec == '2' then | |
− | + | d = string.sub( d, 4, 10 ) | |
− | + | elseif prec == '3' then | |
− | + | d = string.sub( d, 7, 10 ) | |
− | |||
− | |||
end | end | ||
− | return | + | return d |
end | end | ||
Строка 282: | Строка 369: | ||
local function printEvent( gender, rows, i, j ) | local function printEvent( gender, rows, i, j ) | ||
− | local dsc = enumDecode[rows[i].event] | + | local dsc = assert( enumDecode[rows[i].event] ) |
local unitStr, unitref | local unitStr, unitref | ||
if j ~= i then | if j ~= i then | ||
Строка 292: | Строка 379: | ||
ref.refStart() | ref.refStart() | ||
txt = txt .. ref.use( rows[k].ref ) | txt = txt .. ref.use( rows[k].ref ) | ||
+ | if ref.coverRef then | ||
+ | txt = txt .. ' ' .. ref.coverRef | ||
+ | ref.coverRef = nil | ||
+ | end | ||
end | end | ||
table.insert( units, txt ) | table.insert( units, txt ) | ||
end | end | ||
− | unitStr = ' ' .. concat( units) | + | unitStr = ' ' .. concat( units ) |
else | else | ||
if ( rows[i].unit or '' ) ~= '' then | if ( rows[i].unit or '' ) ~= '' then | ||
Строка 304: | Строка 395: | ||
ref.refStart() | ref.refStart() | ||
unitref = ref.use( rows[i].ref ) | unitref = ref.use( rows[i].ref ) | ||
+ | if ref.coverRef then | ||
+ | unitStr = unitStr .. ' ' .. ref.coverRef | ||
+ | ref.coverRef = nil | ||
+ | end | ||
+ | |||
end | end | ||
end | end | ||
assert( dsc[2] or not unitStr ) | assert( dsc[2] or not unitStr ) | ||
− | local text = string.gsub( dsc[1], '%d', | + | local text = string.gsub( dsc[1], '[S%d]', |
− | { ['1'] = gender1[gender], ['2'] = gender2[gender], ['3'] = gender3[gender] } ) | + | { ['1'] = gender1[gender], ['2'] = gender2[gender], ['3'] = gender3[gender], S = dmy( rows[i], 'start' ) } ) |
.. ( unitStr or '' ) | .. ( unitStr or '' ) | ||
− | if ( rows[i].start or '' ) ~= '' then | + | if ( rows[i].start or '' ) ~= '' and not string.find( dsc[1], 'S', 1, true ) then |
text = text .. ' ' .. dmy( rows[i], 'start' ) | text = text .. ' ' .. dmy( rows[i], 'start' ) | ||
end | end | ||
Строка 344: | Строка 440: | ||
if chap ~= lastChap then | if chap ~= lastChap then | ||
if lastChap then | if lastChap then | ||
− | table.insert( out, '<div class=enum-end></div>' ) | + | table.insert( out, '<div class="enum-end enum-collapse collapse"></div>' ) |
end | end | ||
local chapA = mw.text.split( chap, '_' ) | local chapA = mw.text.split( chap, '_' ) | ||
Строка 357: | Строка 453: | ||
lastChapA, lastChap = chapA, chap | lastChapA, lastChap = chapA, chap | ||
chap = table.concat( lastChapA, '_', 1, diff ) | chap = table.concat( lastChapA, '_', 1, diff ) | ||
− | table.insert( out, '<div class=enum-path-on-unitpage>' ) | + | table.insert( out, '<div class="enum-path-on-unitpage enum-collapse collapse">' ) |
for i = diff, #lastChapA do | for i = diff, #lastChapA do | ||
local descr = toc[chap] | local descr = toc[chap] | ||
Строка 366: | Строка 462: | ||
table.insert( out, '<span class=enum-numb>' .. descr[1] .. ' </span>' ) | table.insert( out, '<span class=enum-numb>' .. descr[1] .. ' </span>' ) | ||
end | end | ||
− | table.insert( out, '<span class=enum-name>' .. descr[2] .. ' </span>]]</div>' ) | + | table.insert( out, '<span class=enum-name>' .. descr[2] .. ' </span>]]' ) |
+ | if descr.ref then | ||
+ | table.insert( out, '<p class=small>' ..descr.ref .. '</p>' ) | ||
+ | -- ref.refStart() | ||
+ | -- table.insert( out, ref.use( ) ) | ||
+ | -- ref.refReturn() | ||
+ | end | ||
+ | table.insert( out, '</div>' ) | ||
chap = chap .. '_' .. ( chapA[i+1] or 'ы' ) | chap = chap .. '_' .. ( chapA[i+1] or 'ы' ) | ||
end | end | ||
Строка 381: | Строка 484: | ||
local _, _, gender = lexer.declension( enumrow.unit, 1 ) | local _, _, gender = lexer.declension( enumrow.unit, 1 ) | ||
+ | local extA = data_extT[enumrow.chap] or {} | ||
+ | extA = extA[enumrow.porno] or {} | ||
− | table.insert( out, '<div class=enum-' .. uniclass .. 'row-wrapper><div class=enum-' .. uniclass .. '-wrapper><div class=enum-' .. uniclass .. '>' .. unitLink( enumrow.unit ) ) | + | local printedName |
+ | if extA.show then | ||
+ | printedName = extA.show[1].ref | ||
+ | end | ||
+ | printedName = printedName or dictionary[enumrow.unit] | ||
+ | local eNT = string.match( enumrow.chap, '^s(.-)_' ) | ||
+ | table.insert( out, '<div class="enum-' .. uniclass .. 'row-wrapper enum-N-' .. eNT .. '"><div class=enum-' .. uniclass .. '-wrapper><div class=enum-' .. uniclass .. '>' | ||
+ | .. unitLink( enumrow.unit, printedName, extA.parentlink ) ) | ||
if ( enumrow.ref or '' ) ~= '' then | if ( enumrow.ref or '' ) ~= '' then | ||
ref.refStart() | ref.refStart() | ||
table.insert( out, ref.use( enumrow.ref ) ) | table.insert( out, ref.use( enumrow.ref ) ) | ||
end | end | ||
+ | -- if extA.parentlink then | ||
+ | -- for _, link in ipairs( extA.parentlink ) do | ||
+ | -- table.insert( out, ' <span class=enum-parentlink>' .. unitLink( link.unit, '<i class="fas fa-external-link-alt"></i>' ) .. '</span>' ) | ||
+ | -- end | ||
+ | -- end | ||
table.insert( out, '</div>' ) | table.insert( out, '</div>' ) | ||
− | + | ||
− | + | if extA.add then | |
+ | table.insert( out, '<div class=enum-add>' .. extA.add[1].ref .. '</div>' ) | ||
+ | end | ||
+ | |||
if extA.syn then | if extA.syn then | ||
local synonims = {} | local synonims = {} | ||
Строка 396: | Строка 516: | ||
if syn.start == '' then | if syn.start == '' then | ||
if syn.stop == '' then | if syn.stop == '' then | ||
− | + | -- syntext = 'он' .. gender1[gender] .. ' же' | |
+ | syntext = '' | ||
else | else | ||
− | + | -- syntext = 'до ' .. dmy( syn, 'stop' ) .. ' именовал' .. gender2[gender] | |
+ | syntext = 'до ' .. dmy( syn, 'stop' ) .. ' — ' | ||
end | end | ||
elseif syn.stop == '' then | elseif syn.stop == '' then | ||
− | + | -- syntext = 'c ' .. dmy( syn, 'start' ) .. ' именовал' .. gender2[gender] | |
+ | syntext = 'c ' .. dmy( syn, 'start' ) .. ' — ' | ||
else | else | ||
− | + | -- syntext = 'в период c ' .. dmy( syn, 'start' ) .. ' до ' .. dmy( syn, 'stop' ) .. ' именовал' .. gender2[gender] | |
+ | syntext = 'в период c ' .. dmy( syn, 'start' ) .. ' до ' .. dmy( syn, 'stop' ) .. ' — ' | ||
end | end | ||
− | table.insert( synonims, syntext .. ' ' .. unitLink( syn.unit ) ) | + | table.insert( synonims, '<i>' .. syntext .. '</i>' .. unitLink( syn.unit ) ) |
end | end | ||
− | table.insert( out, '<div class=enum-syn>' .. table.concat( synonims, ', ' ) .. '</div>' ) | + | table.insert( out, '<div class=enum-syn>[' .. table.concat( synonims, ', ' ) .. ']</div>' ) |
end | end | ||
Строка 543: | Строка 667: | ||
table.insert( out, '</div>' ) | table.insert( out, '</div>' ) | ||
− | table.insert( out, '<div class=enum-create-wrapper>' ) | + | if extA.c or extA.num then |
− | + | table.insert( out, '<div class=enum-create-wrapper>' ) | |
− | + | if extA.c then | |
− | + | table.insert( out, '<div class=phone-marker><i class="fa fa-check-circle"></i></div>' ) | |
− | + | local i = 1 | |
− | + | while i <= #extA.c do | |
− | + | local extc = extA.c[i] | |
− | + | local unit = extc.unit | |
− | + | if ( unit or '' ) == '' then | |
− | + | table.insert( out, printEvent( gender, extA.c, i, i ) ) | |
− | + | i = i + 1 | |
− | + | else | |
− | + | local j = i + 1 | |
− | + | local extn = extA.c[j] | |
− | + | while extn and extc.event == extn.event and extc.start == extn.start do | |
− | + | j = j + 1 | |
+ | extn = extA.c[j] | ||
+ | end | ||
+ | table.insert( out, printEvent( gender, extA.c, i, j - 1 ) ) | ||
+ | i = j | ||
end | end | ||
− | |||
− | |||
end | end | ||
end | end | ||
− | + | if extA.num then | |
− | + | table.insert( out, 'Новая нумерация частям дивизии присвоена ' .. dmy( extA.num[1], 'start' ) .. '. ' ) | |
− | + | end | |
+ | else | ||
+ | table.insert( out, '<div class="enum-create-wrapper empty-wrapper">' ) | ||
end | end | ||
table.insert( out, '</div>' ) | table.insert( out, '</div>' ) | ||
Строка 574: | Строка 702: | ||
diabat = diabat[enumrow.porno] | diabat = diabat[enumrow.porno] | ||
if diabat then | if diabat then | ||
− | table.insert( out, '<div class=phone-marker>[[Файл:History swords.png| | + | table.insert( out, '<div class=phone-marker title="В действующей армии">[[Файл:History swords.png|12px|link=]]</div>' ) |
for _, dia in ipairs( diabat ) do | for _, dia in ipairs( diabat ) do | ||
− | table.insert( out, | + | local d1, d2 = dmy( dia, 'start' ), dmy( dia, 'stop' ) |
+ | table.insert( out, | ||
+ | '<span class=date-field>' .. string.rep( '  ', (10-#d1)/3 ) .. d1 .. '</span>-' | ||
+ | .. '<span class=date-field>' .. string.rep( '  ', (10-#d2)/3 ) .. d2 .. '</span> ' ) | ||
end | end | ||
if ( enumrow.ref_battle or '' ) ~= '' then | if ( enumrow.ref_battle or '' ) ~= '' then | ||
Строка 585: | Строка 716: | ||
table.insert( out, '</div>' ) | table.insert( out, '</div>' ) | ||
− | |||
if extA.d then | if extA.d then | ||
+ | table.insert( out, '<div class=enum-death-wrapper>' ) | ||
table.insert( out, '<div class=phone-marker><i class="fa fa-times-circle"></i></div>' ) | table.insert( out, '<div class=phone-marker><i class="fa fa-times-circle"></i></div>' ) | ||
local i = 1 | local i = 1 | ||
Строка 606: | Строка 737: | ||
end | end | ||
end | end | ||
+ | else | ||
+ | table.insert( out, '<div class="enum-death-wrapper empty-wrapper">' ) | ||
end | end | ||
table.insert( out, '</div>' ) | table.insert( out, '</div>' ) | ||
Строка 623: | Строка 756: | ||
local dictionary = {} | local dictionary = {} | ||
local title | local title | ||
− | local function unitfuller( str, badAbbr ) | + | local function unitfuller( str, badAbbr, parents ) |
− | local show, tilda = string.match( | + | local clear = string.match( str, '^(.-)%s*!$' ) |
+ | if not clear then | ||
+ | clear = str | ||
+ | else -- эксперимент, инверсия смысла «!» | ||
+ | parents = nil | ||
+ | end | ||
+ | local show, tilda = string.match( clear, '^([^~]-)%s*~%s*(.*)$' ) | ||
if show then | if show then | ||
if tilda == '' then | if tilda == '' then | ||
tilda = title | tilda = title | ||
end | end | ||
− | + | clear = show .. ' (' .. tilda .. ')' | |
else | else | ||
− | show = | + | show = clear |
end | end | ||
− | local name = report.bigfuller( | + | local name, shorted, overname = report.bigfuller( clear, badAbbr, parents ) |
− | dictionary[name] = show | + | if tilda then |
− | return name | + | -- dictionary[name] = shorted -- 11.12.2021 |
+ | end | ||
+ | -- dictionary[name] = show | ||
+ | return name, shorted, overname | ||
end | end | ||
Строка 648: | Строка 790: | ||
local locno = 0 | local locno = 0 | ||
local data_enum, data_ext, data_battle = {}, {}, {} | local data_enum, data_ext, data_battle = {}, {}, {} | ||
− | title = unitfuller( args[1] ) | + | local parents = {} |
+ | local overname | ||
+ | title, _, overname = unitfuller( args[1], nil, parents, true ) | ||
data_enum[1] = { | data_enum[1] = { | ||
-- en = eN, | -- en = eN, | ||
Строка 663: | Строка 807: | ||
lastUp = porno | lastUp = porno | ||
end | end | ||
+ | |||
+ | if next( parents ) then | ||
+ | data_enum[1].ext = true | ||
+ | for _, parent in ipairs( parents ) do | ||
+ | locno = locno + 1 | ||
+ | table.insert( data_ext, { | ||
+ | chap = label, | ||
+ | porno = porno, | ||
+ | locno = locno, | ||
+ | event = enumEncode.parentlink, | ||
+ | unit = parent, | ||
+ | } ) | ||
+ | end | ||
+ | end | ||
+ | |||
+ | if args['название'] then | ||
+ | data_enum[1].ext = true | ||
+ | locno = locno + 1 | ||
+ | table.insert( data_ext, { | ||
+ | -- en = eN, | ||
+ | chap = label, | ||
+ | porno = porno, | ||
+ | locno = locno, | ||
+ | event = enumEncode.show, | ||
+ | ref = args['название'], | ||
+ | } ) | ||
+ | end | ||
+ | |||
if args['синоним'] then | if args['синоним'] then | ||
Строка 687: | Строка 859: | ||
end | end | ||
+ | end | ||
+ | |||
+ | if args['дополнение'] or overname then | ||
+ | data_enum[1].ext = true | ||
+ | if overname and args['дополнение'] then | ||
+ | overname = overname .. '<br>' | ||
+ | end | ||
+ | local code = enumEncode['прицеп'] | ||
+ | locno = locno + 1 | ||
+ | table.insert( data_ext, { | ||
+ | chap = label, | ||
+ | porno = porno, | ||
+ | locno = locno, | ||
+ | event = code, | ||
+ | ref = ( overname or '' ) .. ( args['дополнение'] or '' ), | ||
+ | } ) | ||
end | end | ||
if args['нумерация'] then | if args['нумерация'] then | ||
data_enum[1].ext = true | data_enum[1].ext = true | ||
− | local date = | + | local date = parseDate( args['нумерация'] ) |
assert( date ~= '' ) | assert( date ~= '' ) | ||
locno = locno + 1 | locno = locno + 1 | ||
Строка 708: | Строка 896: | ||
local creating = mw.text.split( args['создание'], '%s*;%s*' ) | local creating = mw.text.split( args['создание'], '%s*;%s*' ) | ||
assert( #creating == 3, 'Непонятная структура описателя создания' ) | assert( #creating == 3, 'Непонятная структура описателя создания' ) | ||
− | local date = | + | local date = parseDate( creating[3] ) |
local way = mw.ustring.lower( creating[1] ) | local way = mw.ustring.lower( creating[1] ) | ||
local n | local n | ||
Строка 726: | Строка 914: | ||
for _, monosource in ipairs( multisource ) do | for _, monosource in ipairs( multisource ) do | ||
locno = locno + 1 | locno = locno + 1 | ||
+ | local fullunit, _, overname = unitfuller( monosource ) | ||
+ | local unitref = args['сноска/создание'] | ||
+ | if overname then | ||
+ | overname = '-[<i></i>' .. overname .. ']' | ||
+ | if unitref then | ||
+ | unitref = unitref .. '$' .. overname | ||
+ | else | ||
+ | unitref = overname | ||
+ | end | ||
+ | end | ||
table.insert( data_ext, { | table.insert( data_ext, { | ||
-- en = eN, | -- en = eN, | ||
Строка 734: | Строка 932: | ||
event = way, | event = way, | ||
start = date, | start = date, | ||
− | ref = | + | ref = unitref, |
} ) | } ) | ||
end | end | ||
Строка 741: | Строка 939: | ||
if args['судьба'] then | if args['судьба'] then | ||
data_enum[1].ext = true | data_enum[1].ext = true | ||
− | local | + | local deaths = mw.text.split( args['судьба'], '%s*&%s*' ) |
− | + | for _, deathPart in ipairs( deaths ) do | |
− | + | local death = mw.text.split( deathPart, '%s*;%s*' ) | |
− | + | local date = parseDate( death[3] ) | |
− | + | local way = mw.ustring.lower( death[1] ) | |
− | + | way = string.gsub( way, ' во$', ' в' ) | |
− | + | local n | |
− | + | way, n = mw.ustring.gsub( way, '^([^ ]+[ае]н)[аоы]? ', '%1 ' ) | |
− | + | if n == 0 then | |
− | + | way, n = mw.ustring.gsub( way, '(расформирован)[аоы]?', '%1' ) | |
− | + | end | |
− | + | if n == 0 then | |
− | + | way, n = mw.ustring.gsub( way, '(шл)[аои]? ', '%1 ' ) | |
− | + | end | |
− | + | assert( enumEncode['-|' .. way], ' неведомая судьба: «' .. way .. '»' ) | |
− | + | way = enumEncode['-|' .. way] | |
− | + | if ( death[2] or '' ) ~= '' then | |
+ | local multitarget = mw.text.split( death[2], '%s*%+%s*' ) | ||
+ | for _, monotarget in ipairs( multitarget ) do | ||
+ | locno = locno + 1 | ||
+ | local fullunit, _, overname = unitfuller( monotarget ) | ||
+ | local unitref = args['сноска/судьба'] | ||
+ | if overname then | ||
+ | overname = '-[<i></i>' .. overname .. ']' | ||
+ | if unitref then | ||
+ | unitref = unitref .. '$' .. overname | ||
+ | else | ||
+ | unitref = overname | ||
+ | end | ||
+ | end | ||
+ | table.insert( data_ext, { | ||
+ | -- en = eN, | ||
+ | chap = label, | ||
+ | porno = porno, | ||
+ | locno = locno, | ||
+ | unit = fullunit, | ||
+ | event = way, | ||
+ | start = date, | ||
+ | ref = unitref, | ||
+ | } ) | ||
+ | end | ||
+ | else | ||
locno = locno + 1 | locno = locno + 1 | ||
table.insert( data_ext, { | table.insert( data_ext, { | ||
− | -- | + | -- en = eN, |
chap = label, | chap = label, | ||
porno = porno, | porno = porno, | ||
locno = locno, | locno = locno, | ||
− | unit = | + | unit = nil, |
event = way, | event = way, | ||
start = date, | start = date, | ||
Строка 770: | Строка 993: | ||
} ) | } ) | ||
end | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
Строка 821: | Строка 1032: | ||
child = mw.text.trim( a ) | child = mw.text.trim( a ) | ||
end | end | ||
+ | |||
+ | child = string.gsub( child, '%{([^%}]+)%}', function ( str ) | ||
+ | return hiddenRef[tonumber( str )] | ||
+ | end ) | ||
+ | |||
local obra, childN, tail = string.match( child, '^(%(?)%s*([^[%*]+)(.*)$' ) | local obra, childN, tail = string.match( child, '^(%(?)%s*([^[%*]+)(.*)$' ) | ||
assert( obra ) | assert( obra ) | ||
Строка 835: | Строка 1051: | ||
assert( childD ) | assert( childD ) | ||
elseif group and cbra == '' then | elseif group and cbra == '' then | ||
− | + | if string.sub( childN, -1 ) == ')' then | |
local _, o = string.gsub( childN, '%(', function () end ) | local _, o = string.gsub( childN, '%(', function () end ) | ||
local _, c = string.gsub( childN, '%)', function () end ) | local _, c = string.gsub( childN, '%)', function () end ) | ||
Строка 853: | Строка 1069: | ||
end ) | end ) | ||
end | end | ||
− | + | -- childN = unitfuller( childN, { ['минд'] = 'минометный дивизион' } ) | |
+ | childN = unitfuller( childN, mw.loadData('Module:Redata').BadEnum ) | ||
-- dictionary[full], childN = childN, full | -- dictionary[full], childN = childN, full | ||
-- mw.log( obra .. ' | ' .. childN .. ' | ' .. tail .. ' | ' .. ( childD or '' ) .. ' | ' .. cbra ) | -- mw.log( obra .. ' | ' .. childN .. ' | ' .. tail .. ' | ' .. ( childD or '' ) .. ' | ' .. cbra ) | ||
Строка 931: | Строка 1148: | ||
end -- for ipairs(состав) | end -- for ipairs(состав) | ||
end -- if args[состав] | end -- if args[состав] | ||
+ | local unitInText = global.get( 'UNIT-IN-TEXT' ) | ||
+ | if unitInText then | ||
+ | data_enum[1].ext = true | ||
+ | for _, v in ipairs( unitInText ) do | ||
+ | locno = locno + 1 | ||
+ | table.insert( data_ext, { | ||
+ | chap = label, | ||
+ | porno = data_enum[1].porno, | ||
+ | locno = locno, | ||
+ | event = enumEncode.unitintext, | ||
+ | unit = v, | ||
+ | } ) | ||
+ | end | ||
+ | global.set( 'UNIT-IN-TEXT' ) | ||
+ | end | ||
local z = '' | local z = '' | ||
if pager then | if pager then | ||
Строка 1104: | Строка 1336: | ||
local queryE = cargo.query( | local queryE = cargo.query( | ||
'enum_ext', | 'enum_ext', | ||
− | 'chap, porno, event, unit, start, stop, ref, CONCAT(chap, ":", porno)=idx', | + | 'chap, porno, event, unit, start, stop, ref, CONCAT(chap, ":", porno)=idx, start__precision, stop__precision', |
{ | { | ||
where = makeWhere( queryA ), | where = makeWhere( queryA ), | ||
Строка 1118: | Строка 1350: | ||
local queryF = cargo.query( | local queryF = cargo.query( | ||
'enum_battle', | 'enum_battle', | ||
− | 'chap, porno, start, stop', | + | 'chap, porno, start, stop, start__precision, stop__precision', |
{ | { | ||
where = makeWhere( queryA ), | where = makeWhere( queryA ), | ||
Строка 1127: | Строка 1359: | ||
return nil | return nil | ||
end | end | ||
− | return unitPrint( queryA, queryE, queryF, {}, name ) | + | return '<div class="enum-path-control enum-collapse collapse show small" data-toggle="collapse" data-target=".enum-collapse"><i>[[#0|Показать наименования перечней?]]</i></div>' |
+ | .. enumHeader | ||
+ | .. unitPrint( queryA, queryE, queryF, {}, name ) | ||
--[====[ | --[====[ | ||
Строка 1237: | Строка 1471: | ||
local args = tools.checkargs( frame:getParent().args, { | local args = tools.checkargs( frame:getParent().args, { | ||
true, ['сноска'] = true, ['синоним'] = true, | true, ['сноска'] = true, ['синоним'] = true, | ||
+ | ['дополнение'] = true, ['название'] = true, | ||
['состав'] = true, -- ['сноска/состав'] = true, | ['состав'] = true, -- ['сноска/состав'] = true, | ||
['создание'] = true, ['сноска/создание'] = true, | ['создание'] = true, ['сноска/создание'] = true, | ||
Строка 1249: | Строка 1484: | ||
local args = tools.checkargs( frame:getParent().args, { | local args = tools.checkargs( frame:getParent().args, { | ||
true, ['сноска'] = true, ['синоним'] = true, | true, ['сноска'] = true, ['синоним'] = true, | ||
+ | ['дополнение'] = true, | ||
['создание'] = true, ['сноска/создание'] = true, | ['создание'] = true, ['сноска/создание'] = true, | ||
['судьба'] = true, ['сноска/судьба'] = true, | ['судьба'] = true, ['сноска/судьба'] = true, | ||
Строка 1263: | Строка 1499: | ||
if pager or not args[1] then | if pager or not args[1] then | ||
ref.refStart() | ref.refStart() | ||
− | return '<div class=enum-end></div>' .. ref.refOut() | + | return '<div class=enum-end></div>' .. ref.refOut() .. '</div>' |
end | end | ||
end | end | ||
return p | return p |
Текущая версия на 20:55, 16 декабря 2021
Для документации этого модуля может быть создана страница Модуль:Enumeration/doc
local p = {} local global = mw.ext.luaglobal local tools = require( 'Module:Tools' ) local ref = require( 'Module:Ref' ) local report = require( 'Module:Report' ) local lexer = require( 'Module:Lexer' ) local dataOut = mw.loadData( 'Module:DataOut' ) local cargo = mw.ext.cargo local TYPE_DIV = '2' local TYPE_SUBDIV = '3' local TYPE_SUBCORP = '5' local enumHeader = [[ <div class=enum-table-header> <div class=enum-unitrow-wrapper> <div class=enum-unit-wrapper>Объединение, соединение, часть</div> <div class=enum-create-wrapper>Сведения о создании</div> <div class=enum-time-wrapper>В действующей армии</div> <div class=enum-death-wrapper>Дальнейшая судьба</div> </div> <div class=enum-end> </div> </div> ]] report.space = ' ' --[[ таблица enum -- --ид вики-страницы (в принципе, он есть, но нужен короткий код «перечень+часть»)-- -- --ид раздела «перечень+разделы»-- -- en = номер перечня - char(?) -- chap = метка раздела - varchar(16) -- porno = порно (int) -- unit = объект (наименование вч) - varchar(300) -- type = тип объекта (корпус с корпусными частями, корпусная часть, дивизия с составом, часть из состава дивизии, обычная отдельная часть, подразделение обычной части) — char -- father = порно родителя (для корпусных и дивизионных частей и для подразделений) — int -- add = флаг наличия допфактов? — Boolean -- sa_battle = флаг собственных боевых дат (обычно отсутствует для дивизионных частей) — Boolean -- group = номер группировки внутри дивизии (и настоящей, и мнимой) — char -- refs = все сноски? text(2048) таблица enum_add -- en+chap+porno = связь (ид вики-страницы + порно) перечень-метка-порно -- what = тип факта (строка в ??? символов) -- sec_unit = наименование связанной вч — varchar(300) -- start+stop = дата факта — для фактов типа «экв» и «в составе» нужны диапазоны дат date+date таблица enum_battle -- en+chap+porno = связь (ид вики-страницы + порно) -- start+stop = начальная дата -- конечная дата --]] local function enumLink( eNumb, toc, label ) local descr = toc[label] local part = descr.part if part then part = ' (часть ' .. part .. ')' end return 'РККА:Перечень № ' .. eNumb .. ( part or '' ) .. '#enum-' .. label end function p.Header( frame ) local args = tools.checkargs( frame:getParent().args, { true, true, -- номер перечня и метка раздела true, -- признак фиктивного заголовка } ) local eN = args[1] local toc = require( 'Module:EnumTOC/' .. eN ) local myLabel = mw.text.trim( args[2] ) local myDescr = toc[myLabel] local pager = tonumber( mw.title.getCurrentTitle().subpageText ) if pager then pager = '.' .. string.sub( '0' .. pager, -2, -1 ) end local fiction = args[3] assert( not fiction or fiction == '-', 'Ошибка в признаке фиктивного заголовка' ) local out = {} -- можно и для остальных так проверять первый заголовок if not global.get( 'enum-page' ) then table.insert( out, frame:callParserFunction{ name = '#seo', args = { '', description = 'Перечень № ' .. eN .. '. ' .. ( toc.short or 'Состав действуюшей армии в период Великой отечественной войны' ) .. '.', keywords = 'перечни, действующая армия, Великая Отечественная война, боевой состав', } } ) if pager then table.insert( out, '[[Category:Перечни (формирование БД)|' .. string.sub( '0' .. eN, -2, -1) .. pager .. ']]<div class=show-disambig>' ) else table.insert( out, '[[Category:Перечни|' .. string.sub( '0' .. eN, -2, -1).. ']]<div>' ) end end if not myDescr.up then table.insert( out, '<div class=enum-toc><div class=enum-toc-header>Оглавление</div>' ) table.insert( out, require( 'Module:EnumTOC' ).makeTOC( eN ) ) table.insert( out, '</div>' ) table.insert( out, enumHeader ) end if not fiction then if myDescr.up and toc[myDescr.up].part ~= myDescr.part and not myDescr.left or myDescr.left and toc[myDescr.left].part ~= myDescr.part then -- первый заголовок текущей части, надо выводить оглавление вышестоящих -- оно не может быть пустым (это точно не уровень перечня), раз есть верхний или левый элемент -- Все они точно в другой части local label = myDescr.up local outPos = #out+1 repeat local descr = toc[label] local outline = { '<div class="enum-toc-' .. descr.level .. '">' } if descr.left then table.insert( outline, '<span class=enum-left-link>[[' .. enumLink( eN, toc, descr.left ) .. '|<i class="far fa-caret-square-left></i>]] </span>' ) end table.insert( outline, '[[' .. enumLink( eN, toc, label ) .. '|' ) if descr[1] ~= '' then table.insert( outline, '<span class=enum-numb>' .. descr[1] .. ' </span>' ) end table.insert( outline, '<span class=enum-name>' .. descr[2] .. ' </span>]]' ) if descr.right then table.insert( outline, '<span class=enum-right-link> [[' .. enumLink( eN, toc, descr.right ) .. '|<i class="far fa-caret-square-right></i>]]</span>' ) end table.insert( outline, '</div>\n' ) table.insert( out, outPos, table.concat( outline ) ) label = descr.up until not label table.insert( out, outPos, '<div class=enum-path>' ) table.insert( out, '</div>' ) -- GLOBAL_enum = eN elseif myDescr.up and toc[myDescr.up].down ~= myLabel then table.insert( out, '<div class=enum-end></div>' ) end table.insert( out, '<div id="enum-' .. myLabel .. '" class="enum-header enum-toc-' .. myDescr.level .. '">' ) if myDescr.left then table.insert( out, '<span class=enum-path-left-link>[[' .. enumLink( eN, toc, myDescr.left ) .. '|<i class="far fa-caret-square-left></i>]] </span>' ) end if myDescr[1] ~= '' then table.insert( out, '<span class=enum-numb>' .. myDescr[1] .. ' </span>' ) end table.insert( out, '<span class=enum-name>' .. myDescr[2] .. ' </span>' ) if myDescr.right then table.insert( out, '<span class=enum-path-right-link> [[' .. enumLink( eN, toc, myDescr.right ) .. '|<i class="far fa-caret-square-right></i>]]</span>' ) end table.insert( out, '</div>' ) end global.set( 'enum-page', { eN, myLabel .. ( pager or '' ), 0, 0, pager } ) return table.concat( out ) end local gender1 = { ['м'] = '', ['ж'] = 'а', ['с'] = 'о', ['х'] = 'и', } local gender2 = { ['м'] = 'ся', ['ж'] = 'ась', ['с'] = 'ось', ['х'] = 'ись', } local gender3 = { ['м'] = '', ['ж'] = 'а', ['с'] = 'о', ['х'] = 'ы', } local mLength = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } local function parseDate( txt ) if txt == '' then return '' end local res = mw.text.split( txt, '.', true ) assert( #res <= 3, 'Кривая дата' ) local d, m, y = res[#res-2], res[#res-1], res[#res] y = tonumber( y ) assert( y, 'это не дата' ) if y < 100 then y = y+1900 end assert( y >= 1939 and y <= 1946, 'недопустимый номер года' ) res = tostring( y ) if m then m = tonumber( m ) assert( m >= 1 and m <= 12, 'недопустимый номер месяца' ) res = res .. '-' .. string.sub( '0' .. m, -2, -1 ) if d then d = tonumber( d ) assert( d >= 1 and d <= mLength[m] and ( m ~= 2 or d ~= 29 or y % 4 == 0 ), 'недопустимое число в месяце' ) res = res .. '-' .. string.sub( '0' .. d, -2, -1 ) end end return res end local function parseSingleInterval( str, hard ) local dates = mw.text.split( str, '%s*%-%s*' ) assert( #dates == 2, 'Нет диапазона дат' ) local start = parseDate( dates[1] ) assert( start, 'Плохая дата ' .. dates[1] ) local finish = parseDate( dates[2] ) assert( finish, 'Плохая дата ' .. dates[2] ) if start == '' or finish == '' then assert( not hard, 'Должны быть заданы обе границы интервала дат' ) else assert( start <= finish, 'Извращенный диапазон дат' ) end return start, finish end local function parseMultiInterval( str, hard ) local diaps = mw.text.split( mw.text.trim( str ), '%s*[,;]%s*' ) local res = {} for _, diap in ipairs( diaps ) do local start, finish = parseSingleInterval( diap, hard ) table.insert( res, { start, finish } ) end return res end local function concat( tab ) assert( type( tab ) == 'table' and #tab ~= 0 ) if #tab == 1 then return tab[1] end return table.concat( tab, ', ', 1, #tab - 1 ) .. ' и ' .. tab[#tab] end --[[ en Integer номер перечня chap String(size=16) метка раздела porno Integer unit String(size=300) наименование части (соединения) type String(size=1) тип объекта ("0" — обычная часть; "1" — подразделение обычной части; "2" — дивизия; "3" — часть из состава дивизии; "4" — корпус; "5" — корпусная часть) top Integer porno родителя ext Boolean наличие дополнительной информации battle Boolean наличие собственного боевого периода unitgroup String(size=1) группировка частей внутри дивизии ref Text(size=2048) сноска ref_battle Text(size=2048) сноска к боевому периоду --]] --[[ en Integer номер перечня chap String(size=16) метка раздела porno Integer event Integer тип расширенной информации (всё надо пронумеровать) unit String(size=300) наименование части (соединения), связанной по данному событию start Date начало периода события (или дата события) stop Date конец периода события (или пусто, если событие мгновенное) ref Text(size=2048) сноска --]] local function unitPrint( data_enum, data_ext, data_battle, dictionary, nameHL ) local lowNameHL = {} if type( nameHL ) == 'string' then lowNameHL = { [mw.ustring.lower( nameHL )] = true } elseif type( nameHL ) == 'table' then for _, u in ipairs( nameHL ) do lowNameHL[mw.ustring.lower( u )] = true end end local function markHL( unit, str ) if lowNameHL[mw.ustring.lower( unit )] then return '<span class=enum-highlight>' .. ( str or unit ) .. '</span>' end return str or unit end local function unitLink( unit, text, parents ) if text or not parents then return '[[' .. unit .. '|' .. markHL( unit, text ) .. ']]' end local body = unit local shorted, parent, 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 ) ) if dataOut.generation[el] then generation = ' (' .. el .. ')' elseif dataOut.foreigner[el] then foreign = ' (' .. el .. ')' else parent = el end end until not shorted if parent then local stored = {} 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 part = --[[report.bigfuller( ( ]] string.gsub( part, '&(.)', function ( u ) return stored[string.byte( u ) - 96] end ) --[[ ) ) ]] if ( parents[i].unit or '' ) ~= '' then parts[i] = '[[' .. parents[i].unit .. '|' .. markHL( parents[i].unit, part ) .. ']]' else parts[i] = part end end -- parent = ' (' .. string.gsub( table.concat( parts, ', ' ), ' формирования%)', '%)' ) .. ')' parent = ' (' .. table.concat( parts, ', ' ) .. ')' end return '[[' .. unit .. '|' .. markHL( unit, body .. ( foreign or '' ) ) .. ']]' .. ( parent or '' ) .. ( generation or '' ) end -- local function dmy( arr, field ) -- local d=arr[field] -- if string.sub( d, 5, 5 ) == '-' then -- данные из базы -- d = tools.dmy( d ) -- local prec = arr[field .. '__precision'] -- if prec == 2 then -- d = string.sub( d, 4, 10 ) -- elseif prec == 3 then -- d = string.sub( d, 7, 10 ) -- end -- end -- return string.rep( ' ', #d-10 ) .. d -- end local function dmy( arr, field ) local d=arr[field] d = tools.dmy( d ) local prec = arr[field .. '__precision'] -- если из базы if prec == '2' then d = string.sub( d, 4, 10 ) elseif prec == '3' then d = string.sub( d, 7, 10 ) end return d end local function diap2text( tree ) local diapsPrint = {} for _, diap in ipairs( tree ) do local txt if diap.start == '' then txt = 'до ' .. dmy( diap, 'stop' ) elseif diap.stop == '' then txt = 'с ' .. dmy( diap, 'start' ) else txt = 'с ' .. dmy( diap, 'start' ) .. ' до ' .. dmy( diap, 'stop' ) end table.insert( diapsPrint, txt ) end return concat( diapsPrint ) end local enumDecode = mw.loadData( 'Module:EnumDecode' ) local function printEvent( gender, rows, i, j ) local dsc = assert( enumDecode[rows[i].event] ) local unitStr, unitref if j ~= i then local units = {} for k = i, j do local txt = unitLink( rows[k].unit, lexer.declension( rows[k].unit, dsc[2] ) or ('<span class=err> ¿ ' .. rows[k].unit .. ' ? </span>' ) ) if ( rows[k].ref or '' ) ~= '' then ref.refStart() txt = txt .. ref.use( rows[k].ref ) if ref.coverRef then txt = txt .. ' ' .. ref.coverRef ref.coverRef = nil end end table.insert( units, txt ) end unitStr = ' ' .. concat( units ) else if ( rows[i].unit or '' ) ~= '' then unitStr = ' ' .. unitLink( rows[i].unit, lexer.declension( rows[i].unit, dsc[2] ) or ('<span class=err> ¿ ' .. rows[i].unit .. ' ? </span>' ) ) end if ( rows[i].ref or '' ) ~= '' then ref.refStart() unitref = ref.use( rows[i].ref ) if ref.coverRef then unitStr = unitStr .. ' ' .. ref.coverRef ref.coverRef = nil end end end assert( dsc[2] or not unitStr ) local text = string.gsub( dsc[1], '[S%d]', { ['1'] = gender1[gender], ['2'] = gender2[gender], ['3'] = gender3[gender], S = dmy( rows[i], 'start' ) } ) .. ( unitStr or '' ) if ( rows[i].start or '' ) ~= '' and not string.find( dsc[1], 'S', 1, true ) then text = text .. ' ' .. dmy( rows[i], 'start' ) end return text .. ( unitref or '' ) .. '. ' end local data_extT = {} for _, ext in ipairs( data_ext ) do ext.event = tonumber( ext.event ) data_extT[ext.chap] = data_extT[ext.chap] or {} data_extT[ext.chap][ext.porno] = data_extT[ext.chap][ext.porno] or {} data_extT[ext.chap][ext.porno][enumDecode[ext.event].group] = data_extT[ext.chap][ext.porno][enumDecode[ext.event].group] or {} table.insert( data_extT[ext.chap][ext.porno][enumDecode[ext.event].group], ext ) end local data_batT = {} for _, dia in ipairs( data_battle ) do data_batT[dia.chap] = data_batT[dia.chap] or {} data_batT[dia.chap][dia.porno] = data_batT[dia.chap][dia.porno] or {} table.insert( data_batT[dia.chap][dia.porno], dia ) end local rowCnt = 1 local enumrow = data_enum[1] local out = {} local nextrow local lastChapA, lastChap = {} local eN, toc while enumrow do if nameHL then -- запрос со страницы формирования, надо печатать заголовки local chap = string.match( enumrow.chap, '^(.+)%.' ) if chap ~= lastChap then if lastChap then table.insert( out, '<div class="enum-end enum-collapse collapse"></div>' ) end local chapA = mw.text.split( chap, '_' ) local diff = 0 repeat diff = diff + 1 until chapA[diff] ~= lastChapA[diff] if diff == 1 then eN = tonumber( string.sub( chapA[1], 2, 3 ) ) toc = require( 'Module:EnumTOC/' .. eN ) end lastChapA, lastChap = chapA, chap chap = table.concat( lastChapA, '_', 1, diff ) table.insert( out, '<div class="enum-path-on-unitpage enum-collapse collapse">' ) for i = diff, #lastChapA do local descr = toc[chap] -- mw.log( chap ) table.insert( out, '<div class="enum-toc-' .. descr.level .. '">' .. '[[' .. enumLink( eN, toc, chap ) .. '|' ) if descr[1] ~= '' then table.insert( out, '<span class=enum-numb>' .. descr[1] .. ' </span>' ) end table.insert( out, '<span class=enum-name>' .. descr[2] .. ' </span>]]' ) if descr.ref then table.insert( out, '<p class=small>' ..descr.ref .. '</p>' ) -- ref.refStart() -- table.insert( out, ref.use( ) ) -- ref.refReturn() end table.insert( out, '</div>' ) chap = chap .. '_' .. ( chapA[i+1] or 'ы' ) end table.insert( out, '</div>' ) end end local uniclass if ( enumrow.top or '' ) == '' then uniclass = 'unit' else uniclass = 'subu' end local _, _, gender = lexer.declension( enumrow.unit, 1 ) local extA = data_extT[enumrow.chap] or {} extA = extA[enumrow.porno] or {} local printedName if extA.show then printedName = extA.show[1].ref end printedName = printedName or dictionary[enumrow.unit] local eNT = string.match( enumrow.chap, '^s(.-)_' ) table.insert( out, '<div class="enum-' .. uniclass .. 'row-wrapper enum-N-' .. eNT .. '"><div class=enum-' .. uniclass .. '-wrapper><div class=enum-' .. uniclass .. '>' .. unitLink( enumrow.unit, printedName, extA.parentlink ) ) if ( enumrow.ref or '' ) ~= '' then ref.refStart() table.insert( out, ref.use( enumrow.ref ) ) end -- if extA.parentlink then -- for _, link in ipairs( extA.parentlink ) do -- table.insert( out, ' <span class=enum-parentlink>' .. unitLink( link.unit, '<i class="fas fa-external-link-alt"></i>' ) .. '</span>' ) -- end -- end table.insert( out, '</div>' ) if extA.add then table.insert( out, '<div class=enum-add>' .. extA.add[1].ref .. '</div>' ) end if extA.syn then local synonims = {} for _, syn in ipairs( extA.syn ) do local syntext if syn.start == '' then if syn.stop == '' then -- syntext = 'он' .. gender1[gender] .. ' же' syntext = '' else -- syntext = 'до ' .. dmy( syn, 'stop' ) .. ' именовал' .. gender2[gender] syntext = 'до ' .. dmy( syn, 'stop' ) .. ' — ' end elseif syn.stop == '' then -- syntext = 'c ' .. dmy( syn, 'start' ) .. ' именовал' .. gender2[gender] syntext = 'c ' .. dmy( syn, 'start' ) .. ' — ' else -- syntext = 'в период c ' .. dmy( syn, 'start' ) .. ' до ' .. dmy( syn, 'stop' ) .. ' именовал' .. gender2[gender] syntext = 'в период c ' .. dmy( syn, 'start' ) .. ' до ' .. dmy( syn, 'stop' ) .. ' — ' end table.insert( synonims, '<i>' .. syntext .. '</i>' .. unitLink( syn.unit ) ) end table.insert( out, '<div class=enum-syn>[' .. table.concat( synonims, ', ' ) .. ']</div>' ) end if enumrow.type == TYPE_DIV then -- состав local subarr = {} local subCnt = rowCnt repeat subCnt = subCnt + 1 local subrow = data_enum[subCnt] if not subrow or subrow.type ~= TYPE_SUBDIV then -- table.insert( out, mw.dumpObject( subrow ) ) break end local subExtA = data_extT[subrow.chap] or {} subExtA = subExtA[subrow.porno] or {} -- assert( dictionary[subrow.unit] ) if ( subrow.unitgroup or '' ) ~= '' then -- группа local subdia = subExtA.set local nextGrow = data_enum[subCnt+1] -- assert( nextGrow, 'не след. за ' .. subrow.unit ) -- assert( nextGrow.chap == subrow.chap and data_extT[nextGrow.chap], '++ не след. за ' .. subrow.unit .. '\n' .. mw.dumpObject(data_enum) ) local nextGdia = data_extT[nextGrow.chap] or {} nextGdia = nextGdia[nextGrow.porno] or {} --- nextrow.chap = subrow.chap nextGdia = nextGdia.set if not subdia --[[ aka and not nextGdia ]] or subdia[1].start == nextGdia[1].start then -- группа без раскладки по датам local commontext subrow.printtext = dictionary[subrow.unit] or report.shorter( subrow.unit ) subrow.num, commontext = string.match( subrow.printtext, '^(%d+)[ \160](.+)$' ) local i = subCnt + 1 while nextGrow.unitgroup == subrow.unitgroup do nextGrow.printtext = dictionary[nextGrow.unit] or report.shorter( nextGrow.unit ) if commontext then nextGrow.num = string.match( nextGrow.printtext, '^(%d+) ' .. commontext .. '$' ) if not nextGrow.num then commontext = nil end end i = i + 1 nextGrow = data_enum[i] or {} end local printtext if commontext then printtext = subrow.num else printtext = subrow.printtext end printtext = unitLink( subrow.unit, printtext ) if ( subrow.ref or '' ) ~= '' then ref.refStart() printtext = printtext .. ref.use( subrow.ref ) end local group = {} nextGrow = data_enum[subCnt+1] i = subCnt+1 while nextGrow.unitgroup == subrow.unitgroup do local printtext if commontext then printtext = nextGrow.num else printtext = nextGrow.printtext end printtext = unitLink( nextGrow.unit, printtext ) if ( nextGrow.ref or '' ) ~= '' then ref.refStart() printtext = printtext .. ref.use( nextGrow.ref ) end table.insert( group, printtext ) i = i + 1 nextGrow = data_enum[i] or {} end printtext = printtext .. ' (' .. table.concat( group, ', ' ) .. ')' if commontext then printtext = printtext .. ' ' .. commontext end if subExtA.set then printtext = printtext .. ' — <i>' .. diap2text( subExtA.set ) .. '</i>' end table.insert( subarr, printtext ) subCnt = i - 1 -- table.insert( subarr, 'GROUP-SYN' ) else -- группа с раскладкой по датам — всегда ровно два элемента -- assert( group[1].limits[1][1] == group[2].limits[1][2] and group[1].limits[1][2] == '' and group[2].limits[1][1] == '' -- А (до ххх — B) -- or group[1].limits[1][2] == group[2].limits[1][1] and group[1].limits[1][1] == '' and group[2].limits[1][2] == '' -- А (с ххх — В) -- or group[1].limits[1][2] == group[2].limits[1][1] and group[1].limits[2][1] == group[2].limits[1][2] -- and group[1].limits[1][1] == '' and group[1].limits[2][2] == '', 'Неприемлемая группировка сроков' ) -- А (с ххх до ууу — В) local printtext = unitLink( subrow.unit, dictionary[subrow.unit] or report.shorter( subrow.unit ) ) if ( subrow.ref or '' ) ~= '' then ref.refStart() printtext = printtext .. ref.use( subrow.ref ) end printtext = printtext .. ' (<i>' .. diap2text( nextGdia ) .. '</i> — ' printtext = printtext .. unitLink( nextGrow.unit, dictionary[nextGrow.unit] or report.shorter( nextGrow.unit ) ) if ( nextGrow.ref or '' ) ~= '' then ref.refStart() printtext = printtext .. ref.use( nextGrow.ref ) end printtext = printtext .. ')' table.insert( subarr, printtext ) subCnt = subCnt + 1 -- table.insert( subarr, 'GROUP-SEQ' ) -- while subrow.unitgroup == nextGrow.unitgroup do -- subCnt = subCnt + 1 -- subrow = data_enum[subCnt] or {} -- end -- subCnt = subCnt - 1 end else -- не группа local text = unitLink( subrow.unit, dictionary[subrow.unit] or report.shorter( subrow.unit ) ) if subExtA.set then text = text .. ' — <i>' .. diap2text( subExtA.set ) .. '</i>' end if ( subrow.ref or '' ) ~= '' then ref.refStart() text = text .. ref.use( subrow.ref ) end table.insert( subarr, text ) end until false nextrow = subCnt table.insert( out, '<div class=enum-set-wrapper>' ) table.insert( out, table.concat( subarr, ', ' ) ) table.insert( out, '</div>' ) else nextrow = rowCnt + 1 end table.insert( out, '</div>' ) if extA.c or extA.num then table.insert( out, '<div class=enum-create-wrapper>' ) if extA.c then table.insert( out, '<div class=phone-marker><i class="fa fa-check-circle"></i></div>' ) local i = 1 while i <= #extA.c do local extc = extA.c[i] local unit = extc.unit if ( unit or '' ) == '' then table.insert( out, printEvent( gender, extA.c, i, i ) ) i = i + 1 else local j = i + 1 local extn = extA.c[j] while extn and extc.event == extn.event and extc.start == extn.start do j = j + 1 extn = extA.c[j] end table.insert( out, printEvent( gender, extA.c, i, j - 1 ) ) i = j end end end if extA.num then table.insert( out, 'Новая нумерация частям дивизии присвоена ' .. dmy( extA.num[1], 'start' ) .. '. ' ) end else table.insert( out, '<div class="enum-create-wrapper empty-wrapper">' ) end table.insert( out, '</div>' ) table.insert( out, '<div class=enum-time-wrapper>' ) local diabat = data_batT[enumrow.chap] or {} diabat = diabat[enumrow.porno] if diabat then table.insert( out, '<div class=phone-marker title="В действующей армии">[[Файл:History swords.png|12px|link=]]</div>' ) for _, dia in ipairs( diabat ) do local d1, d2 = dmy( dia, 'start' ), dmy( dia, 'stop' ) table.insert( out, '<span class=date-field>' .. string.rep( '  ', (10-#d1)/3 ) .. d1 .. '</span>-' .. '<span class=date-field>' .. string.rep( '  ', (10-#d2)/3 ) .. d2 .. '</span> ' ) end if ( enumrow.ref_battle or '' ) ~= '' then ref.refStart() table.insert( out, ref.use( enumrow.ref_battle ) ) end end table.insert( out, '</div>' ) if extA.d then table.insert( out, '<div class=enum-death-wrapper>' ) table.insert( out, '<div class=phone-marker><i class="fa fa-times-circle"></i></div>' ) local i = 1 while i <= #extA.d do local extc = extA.d[i] local unit = extc.unit if ( unit or '' ) == '' then table.insert( out, printEvent( gender, extA.d, i, i ) ) i = i + 1 else local j = i + 1 local extn = extA.d[j] while extn and extc.event == extn.event and extc.start == extn.start do j = j + 1 extn = extA.d[j] end table.insert( out, printEvent( gender, extA.d, i, j - 1 ) ) i = j end end else table.insert( out, '<div class="enum-death-wrapper empty-wrapper">' ) end table.insert( out, '</div>' ) table.insert( out, '</div>' ) rowCnt = nextrow enumrow = data_enum[rowCnt] end if nameHL then table.insert( out, '<div class=enum-end></div>' ) end return table.concat( out ) end local function unitrow( args, subunit ) local enumEncode = mw.loadData( 'Module:EnumEncode' ) local dictionary = {} local title local function unitfuller( str, badAbbr, parents ) local clear = string.match( str, '^(.-)%s*!$' ) if not clear then clear = str else -- эксперимент, инверсия смысла «!» parents = nil end local show, tilda = string.match( clear, '^([^~]-)%s*~%s*(.*)$' ) if show then if tilda == '' then tilda = title end clear = show .. ' (' .. tilda .. ')' else show = clear end local name, shorted, overname = report.bigfuller( clear, badAbbr, parents ) if tilda then -- dictionary[name] = shorted -- 11.12.2021 end -- dictionary[name] = show return name, shorted, overname end -- local uniclass -- if subunit then -- uniclass = 'subu' -- else -- uniclass = 'unit' -- end local eN, label, porno, lastUp, pager = unpack( global.get( 'enum-page' ) ) porno = porno+1 local locno = 0 local data_enum, data_ext, data_battle = {}, {}, {} local parents = {} local overname title, _, overname = unitfuller( args[1], nil, parents, true ) data_enum[1] = { -- en = eN, chap = label, porno = porno, unit = title, ref = args['сноска'], unitgroup = nil, } if subunit then data_enum[1].top = lastUp data_enum[1].type = TYPE_SUBCORP else lastUp = porno end if next( parents ) then data_enum[1].ext = true for _, parent in ipairs( parents ) do locno = locno + 1 table.insert( data_ext, { chap = label, porno = porno, locno = locno, event = enumEncode.parentlink, unit = parent, } ) end end if args['название'] then data_enum[1].ext = true locno = locno + 1 table.insert( data_ext, { -- en = eN, chap = label, porno = porno, locno = locno, event = enumEncode.show, ref = args['название'], } ) end if args['синоним'] then data_enum[1].ext = true local syns = mw.text.split( args['синоним'], '%s*&%s*' ) for _, syn in ipairs( syns ) do local el = mw.text.split( syn, '%s*;%s*' ) assert( #el == 3, 'Ошибка в описании альтернативного наименования (' .. syn .. ')' ) local code = enumEncode[el[1]] assert( code, 'Неизвестный описатель альтернативного наименования' ) local start, finish = parseSingleInterval( el[2] ) locno = locno + 1 table.insert( data_ext, { -- en = eN, chap = label, porno = porno, locno = locno, event = code, unit = unitfuller( el[3] ), start = start, stop = finish, ref = args['сноска/синоним'], } ) end end if args['дополнение'] or overname then data_enum[1].ext = true if overname and args['дополнение'] then overname = overname .. '<br>' end local code = enumEncode['прицеп'] locno = locno + 1 table.insert( data_ext, { chap = label, porno = porno, locno = locno, event = code, ref = ( overname or '' ) .. ( args['дополнение'] or '' ), } ) end if args['нумерация'] then data_enum[1].ext = true local date = parseDate( args['нумерация'] ) assert( date ~= '' ) locno = locno + 1 table.insert( data_ext, { -- en = eN, chap = label, porno = porno, locno = locno, event = enumEncode['*|нумерация'], start = date, } ) end if args['создание'] then data_enum[1].ext = true local creating = mw.text.split( args['создание'], '%s*;%s*' ) assert( #creating == 3, 'Непонятная структура описателя создания' ) local date = parseDate( creating[3] ) local way = mw.ustring.lower( creating[1] ) local n way, n = mw.ustring.gsub( way, '([ае]н)[аоы]? из', '%1 из' ) if n == 0 then way, n = mw.ustring.gsub( way, '([ае]н)[аоы]? на базе', '%1 на базе' ) end if n == 0 then way, n = mw.ustring.gsub( way, '(ят)[аоы]? из', '%1 из' ) end if n == 0 then way, n = mw.ustring.gsub( way, '(ыл)[аои]? из', '%1 из' ) end assert( enumEncode['+|' .. way], ' неведомый способ создания: «' .. way .. '»' ) way = enumEncode['+|' .. way] local multisource = mw.text.split( creating[2], '%s*%+%s*' ) for _, monosource in ipairs( multisource ) do locno = locno + 1 local fullunit, _, overname = unitfuller( monosource ) local unitref = args['сноска/создание'] if overname then overname = '-[<i></i>' .. overname .. ']' if unitref then unitref = unitref .. '$' .. overname else unitref = overname end end table.insert( data_ext, { -- en = eN, chap = label, porno = porno, locno = locno, unit = unitfuller( monosource ), event = way, start = date, ref = unitref, } ) end end if args['судьба'] then data_enum[1].ext = true local deaths = mw.text.split( args['судьба'], '%s*&%s*' ) for _, deathPart in ipairs( deaths ) do local death = mw.text.split( deathPart, '%s*;%s*' ) local date = parseDate( death[3] ) local way = mw.ustring.lower( death[1] ) way = string.gsub( way, ' во$', ' в' ) local n way, n = mw.ustring.gsub( way, '^([^ ]+[ае]н)[аоы]? ', '%1 ' ) if n == 0 then way, n = mw.ustring.gsub( way, '(расформирован)[аоы]?', '%1' ) end if n == 0 then way, n = mw.ustring.gsub( way, '(шл)[аои]? ', '%1 ' ) end assert( enumEncode['-|' .. way], ' неведомая судьба: «' .. way .. '»' ) way = enumEncode['-|' .. way] if ( death[2] or '' ) ~= '' then local multitarget = mw.text.split( death[2], '%s*%+%s*' ) for _, monotarget in ipairs( multitarget ) do locno = locno + 1 local fullunit, _, overname = unitfuller( monotarget ) local unitref = args['сноска/судьба'] if overname then overname = '-[<i></i>' .. overname .. ']' if unitref then unitref = unitref .. '$' .. overname else unitref = overname end end table.insert( data_ext, { -- en = eN, chap = label, porno = porno, locno = locno, unit = fullunit, event = way, start = date, ref = unitref, } ) end else locno = locno + 1 table.insert( data_ext, { -- en = eN, chap = label, porno = porno, locno = locno, unit = nil, event = way, start = date, ref = args['сноска/судьба'], } ) end end end if args['период'] then data_enum[1].battle = true local intervals = parseMultiInterval( args['период'], true ) for _, inter in ipairs( intervals ) do table.insert( data_battle, { -- en = eN, chap = label, porno = porno, start = inter[1], stop = inter[2], } ) end data_enum[1].ref_battle = args['сноска/период'] end if args['состав'] then data_enum[1].type = TYPE_DIV local hiddenRef = {} local children = string.gsub( args['состав'], '%{([^}]+)%}', function ( str ) table.insert( hiddenRef, mw.text.trim( str ) ) return '{' .. #hiddenRef .. '}' end ) local hiddenDiap = {} children = string.gsub( children, '%[([^%]]+)%]', function ( str ) table.insert( hiddenDiap, mw.text.trim( str ) ) return '[' .. #hiddenDiap .. ']' end ) children = mw.text.split( children, '%s*,%s*' ) local group local groupMarker = 64 -- string.code( 'A' ) - 1 for _, child in ipairs( children ) do local a, reference = string.match( child, '^([^*]+)%*%s*(.+)$' ) if a then child = mw.text.trim( a ) end child = string.gsub( child, '%{([^%}]+)%}', function ( str ) return hiddenRef[tonumber( str )] end ) local obra, childN, tail = string.match( child, '^(%(?)%s*([^[%*]+)(.*)$' ) assert( obra ) if obra == '(' then assert( not group, 'Вложенные скобки ' .. child ) group = {} groupMarker = groupMarker + 1 end childN = mw.text.trim( childN ) local childD, cbra = nil, '' local limits if tail ~= '' then childD, cbra = string.match( tail, '^%[([^%]]+)%]%s*(%)?)$' ) assert( childD ) elseif group and cbra == '' then if string.sub( childN, -1 ) == ')' then local _, o = string.gsub( childN, '%(', function () end ) local _, c = string.gsub( childN, '%)', function () end ) if c == o + 1 then cbra = ')' childN = mw.text.trim( string.sub( childN, 1, -2 ) ) end end end if childD then childD = hiddenDiap[tonumber( childD )] limits = parseMultiInterval( childD ) end if reference then reference = string.gsub( reference, '%{([^%}]+)%}', function ( str ) return hiddenRef[tonumber( str )] end ) end -- childN = unitfuller( childN, { ['минд'] = 'минометный дивизион' } ) childN = unitfuller( childN, mw.loadData('Module:Redata').BadEnum ) -- dictionary[full], childN = childN, full -- mw.log( obra .. ' | ' .. childN .. ' | ' .. tail .. ' | ' .. ( childD or '' ) .. ' | ' .. cbra ) assert ( obra == '' or cbra == '' ) if group then table.insert( group, { name = childN, diap = childD, limits = limits, ref = reference } ) if cbra ~= '' then assert( group and #group > 1 ) local seq = group[1].diap ~= group[2].diap if seq then assert( #group == 2 ) -- ( 71 гв. обс [-05.05.1943, 14.11.1944-], 71 гв. орс [05.05.1943-14.11.1944] ) assert( group[1].limits[1][1] == group[2].limits[1][2] and group[1].limits[1][2] == '' and group[2].limits[1][1] == '' -- А (до ххх — B) or group[1].limits[1][2] == group[2].limits[1][1] and group[1].limits[1][1] == '' and group[2].limits[1][2] == '' -- А (с ххх — В) or group[1].limits[1][2] == group[2].limits[1][1] and group[1].limits[2][1] == group[2].limits[1][2] and group[1].limits[1][1] == '' and group[1].limits[2][2] == '', 'Неприемлемая группировка сроков' ) -- А (с ххх до ууу — В) end for _, u in ipairs( group ) do porno = porno + 1 locno = 0 table.insert( data_enum, { -- en = eN, chap = label, porno = porno, unit = u.name, type = TYPE_SUBDIV, top = lastUp, unitgroup = string.char( groupMarker ), ref = u.ref, } ) if u.diap then data_enum[#data_enum].ext = true for _, v in ipairs( u.limits ) do locno = locno + 1 table.insert( data_ext, { -- en = eN, chap = label, porno = porno, locno = locno, event = enumEncode['*|в составе дивизии'], start = v[1], stop = v[2], } ) end end end group = nil end else porno = porno + 1 locno = 0 table.insert( data_enum, { -- en = eN, chap = label, porno = porno, unit = childN, type = TYPE_SUBDIV, top = lastUp, ref = reference, } ) if childD then for _, v in ipairs( limits ) do data_enum[#data_enum].ext = true locno = locno + 1 table.insert( data_ext, { -- en = eN, chap = label, porno = porno, locno = locno, event = enumEncode['*|в составе дивизии'], start = v[1], stop = v[2], } ) end end end end -- for ipairs(состав) end -- if args[состав] local unitInText = global.get( 'UNIT-IN-TEXT' ) if unitInText then data_enum[1].ext = true for _, v in ipairs( unitInText ) do locno = locno + 1 table.insert( data_ext, { chap = label, porno = data_enum[1].porno, locno = locno, event = enumEncode.unitintext, unit = v, } ) end global.set( 'UNIT-IN-TEXT' ) end local z = '' if pager then local frame = mw.getCurrentFrame() for _, u in ipairs( data_enum ) do -- z = z .. frame:expandTemplate{ title = 'Таблица строк перечня', args = u } u._table = 'enum' u[1] = '' z = z .. frame:callParserFunction( '#cargo_store', u ) end for _, u in ipairs( data_ext ) do -- z = z .. frame:expandTemplate{ title = 'Таблица расширенной информации перечня', args = u } u._table = 'enum_ext' u[1] = '' z = z .. frame:callParserFunction( '#cargo_store', u ) end for _, u in ipairs( data_battle ) do -- z = z .. frame:expandTemplate{ title = 'Таблица боевых периодов', args = u } u._table = 'enum_battle' u[1] = '' z = z .. frame:callParserFunction( '#cargo_store', u ) end end global.set( 'enum-page', { eN, label, porno, lastUp, pager } ) return unitPrint( data_enum, data_ext, data_battle, dictionary ) end function p.unitQuery( name ) -- запрос из модулей Page и Disambigution -- основные упоминания -- упоминания в расширениях -- родители всех упоминаний -- дети основных упоминаний и упоминаний как синонимов -- 1. собираем основные упоминания (M:[name] = A) -- 2. собираем упоминания в расширениях (X:[name] = B) -- 3. собираем недостающие элементы основной таблицы (M:(B[syn]-A) = C) -- 4. нам нужны родители (M:(A+B) = D) -- 5. Нам нужны дети (M:(A+C) = E) -- 6. Собираем недостающие расширения (X:(A+C+D+E)) local function makeWhere( tab, fieldV, fieldN ) local where = {} for _, u in pairs( tab ) do table.insert( where, 'chap="' .. u.chap .. '" AND ' .. ( fieldN or 'porno' ) .. '=' .. u[fieldV or 'porno'] ) end return '( ' .. table.concat( where, ' OR ' ) .. ' )' end local where if type( name ) == 'table' then where = '( unit="' .. table.concat( name, '" OR unit="' ) .. '" )' else where = 'unit="' .. name .. '"' end local queryA = cargo.query( 'enum', 'chap, porno, unit, type, top, ext, battle, unitgroup, ref, ref_battle, CONCAT(chap, ":", porno)=idx', { where = where, orderBy = 'chap, porno', } ) local need_main = {} local recieved_main = {} local need_children = {} local requery = {} for _, row in ipairs( queryA ) do recieved_main[row.idx] = row need_children[row.idx] = row end local orRecieved = '' if next( recieved_main ) then orRecieved = ' OR event=1 AND ' .. makeWhere( recieved_main ) end local queryB = cargo.query( 'enum_ext', 'chap, porno, locno, event, unit, start, stop, ref, CONCAT(chap, ":", porno)=idx', { where = where .. orRecieved, orderBy = 'chap, porno, locno', } ) for _, row in ipairs( queryB ) do if not recieved_main[row.idx] then table.insert( need_main, row ) if row.event == '1' then need_children[row.idx] = row end else table.insert( requery, row.unit ) end end if #requery ~= 0 then local queryAplus = cargo.query( 'enum', 'chap, porno, unit, type, top, ext, battle, unitgroup, ref, ref_battle, CONCAT(chap, ":", porno)=idx', { where = '( unit="' .. table.concat( requery, '" OR unit="' ) .. '" )', orderBy = 'chap, porno', } ) for _, row in ipairs( queryAplus ) do if not recieved_main[row.idx] then table.insert( queryA, row ) recieved_main[row.idx] = row need_children[row.idx] = row end end end if next( need_main ) then local queryC = cargo.query( 'enum', 'chap, porno, unit, type, top, ext, battle, unitgroup, ref, ref_battle, CONCAT(chap, ":", porno)=idx', { where = makeWhere( need_main ), orderBy = 'chap, porno', } ) for _, row in ipairs( queryC ) do recieved_main[row.idx] = row table.insert( queryA, row ) end end if #queryA == 0 then return nil end -- queryA — массив записей основной таблицы =p.unitQuery('284 бомбардировочная авиационная дивизия') need_main = {} for _, row in ipairs( queryA ) do if row.top ~= '' and not recieved_main[row.chap..':'..row.top] then table.insert( need_main, 'chap="' .. row.chap .. '" AND porno=' .. row.top ) end if row.unitgroup ~= '' then table.insert( need_main, 'chap="' .. row.chap .. '" AND top=' .. row.top .. ' AND unitgroup="' .. row.unitgroup .. '"' ) end -- чревато дубликатами end for _, row in pairs( need_children ) do table.insert( need_main, 'chap="' .. row.chap .. '" AND top=' .. row.porno ) end if #need_main ~= 0 then local queryD = cargo.query( 'enum', 'chap, porno, unit, type, top, ext, battle, unitgroup, ref, ref_battle, CONCAT(chap, ":", porno)=idx', { where = table.concat( need_main, ' OR ' ), orderBy = 'chap, porno', } ) for _, row in ipairs( queryD ) do if not recieved_main[row.idx] then recieved_main[row.idx] = row -- а так мы дубликаты побороли table.insert( queryA, row ) end end end table.sort( queryA, function ( a, b ) return a.chap < b.chap or ( a.chap == b.chap and tonumber( a.porno ) < tonumber( b.porno ) ) end ) local i = 1 while i < #queryA do if queryA[i].idx == queryA[i+1].idx then table.remove( queryA, i ) else i = i + 1 end end -- local need_ext = {} -- for _, row in ipairs( queryA ) do -- table.insert( need_ext, 'chap="' .. row.chap .. '" AND porno=' .. row.porno ) -- end -- if #need_ext ~= 0 then local queryE = cargo.query( 'enum_ext', 'chap, porno, event, unit, start, stop, ref, CONCAT(chap, ":", porno)=idx, start__precision, stop__precision', { where = makeWhere( queryA ), orderBy = 'chap, porno, locno', } ) -- for _, row in ipairs( queryE ) do -- if not recieved_ext[row.idx] then -- table.insert( queryB, row ) -- end -- end -- end local queryF = cargo.query( 'enum_battle', 'chap, porno, start, stop, start__precision, stop__precision', { where = makeWhere( queryA ), orderBy = 'chap, porno, start', } ) if #queryA == 0 then return nil end return '<div class="enum-path-control enum-collapse collapse show small" data-toggle="collapse" data-target=".enum-collapse"><i>[[#0|Показать наименования перечней?]]</i></div>' .. enumHeader .. unitPrint( queryA, queryE, queryF, {}, name ) --[====[ local queryB = cargo.query( 'enum_ext', 'chap, porno, locno, event, unit, start, stop, ref, CONCAT(chap, ":", porno)=idx', { where = where, orderBy = 'chap, porno, locno', } ) for _, row in ipairs( queryB ) do if not recieved_main[row.idx] then table.insert( need_main, row ) end recieved_ext[row.idx] = row if row.event == '1' then need_children[row.idx] = row end end if next( need_main ) then local queryC = cargo.query( 'enum', 'chap, porno, unit, type, top, ext, battle, unitgroup, ref, ref_battle, CONCAT(chap, ":", porno)=idx', { where = makeWhere( need_main ), orderBy = 'chap, porno', } ) for _, row in ipairs( queryC ) do recieved_main[row.idx] = row table.insert( queryA, row ) end end -- queryA — массив записей основной таблицы =p.unitQuery('284 бомбардировочная авиационная дивизия') need_main = {} for _, row in ipairs( queryA ) do if row.top ~= '' and not recieved_main[row.chap..':'..row.top] then table.insert( need_main, 'chap="' .. row.chap .. '" AND porno=' .. row.top ) end if row.unitgroup ~= '' then table.insert( need_main, 'chap="' .. row.chap .. '" AND top=' .. row.top .. ' AND unitgroup="' .. row.unitgroup .. '"' ) end -- чревато жубликатами end for _, row in pairs( need_children ) do table.insert( need_main, 'chap="' .. row.chap .. '" AND top=' .. row.porno ) end if #need_main ~= 0 then local queryD = cargo.query( 'enum', 'chap, porno, unit, type, top, ext, battle, unitgroup, ref, ref_battle, CONCAT(chap, ":", porno)=idx', { where = table.concat( need_main, ' OR ' ), orderBy = 'chap, porno', } ) for _, row in ipairs( queryD ) do if not recieved_main[row.idx] then recieved_main[row.idx] = row table.insert( queryA, row ) end end end table.sort( queryA, function ( a, b ) return a.chap < b.chap or ( a.chap == b.chap and tonumber( a.porno ) < tonumber( b.porno ) ) end ) local need_ext = {} for _, row in ipairs( queryA ) do if not recieved_ext[row.idx] then table.insert( need_ext, 'chap="' .. row.chap .. '" AND porno=' .. row.porno ) end end if #need_ext ~= 0 then local queryE = cargo.query( 'enum_ext', 'chap, porno, event, unit, start, stop, ref, CONCAT(chap, ":", porno)=idx', { where = table.concat( need_ext, ' OR ' ), orderBy = 'chap, porno, locno', } ) for _, row in ipairs( queryE ) do if not recieved_ext[row.idx] then table.insert( queryB, row ) end end end local queryF = cargo.query( 'enum_battle', 'chap, porno, start, stop', { where = makeWhere( queryA ), orderBy = 'chap, porno, start', } ) if #queryA == 0 then return nil end return unitPrint( queryA, queryB, queryF, {}, name ) --]====] end function p.UnitQuery( frame ) return p.unitQuery( frame.args.unit ) end function p.Unit( frame ) local args = tools.checkargs( frame:getParent().args, { true, ['сноска'] = true, ['синоним'] = true, ['дополнение'] = true, ['название'] = true, ['состав'] = true, -- ['сноска/состав'] = true, ['создание'] = true, ['сноска/создание'] = true, ['нумерация'] = true, ['судьба'] = true, ['сноска/судьба'] = true, ['период'] = true, ['сноска/период'] = true, } ) return ref.refReturn( unitrow( args ) ) end function p.Subunit( frame ) local args = tools.checkargs( frame:getParent().args, { true, ['сноска'] = true, ['синоним'] = true, ['дополнение'] = true, ['создание'] = true, ['сноска/создание'] = true, ['судьба'] = true, ['сноска/судьба'] = true, ['период'] = true, ['сноска/период'] = true, } ) return ref.refReturn( unitrow( args, true ) ) end function p.End( frame ) local args = tools.checkargs( frame:getParent().args, { true } ) local pager = tonumber( mw.title.getCurrentTitle().subpageText ) if pager or not args[1] then ref.refStart() return '<div class=enum-end></div>' .. ref.refOut() .. '</div>' end end return p