Модуль:Enumeration: различия между версиями
Материал из Указатель частей и соединений РККА 1941-1945
WikiSysop (обсуждение | вклад) |
WikiSysop (обсуждение | вклад) |
||
Строка 386: | Строка 386: | ||
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 | ||
Строка 396: | Строка 396: | ||
unitref = ref.use( rows[i].ref ) | unitref = ref.use( rows[i].ref ) | ||
if ref.coverRef then | if ref.coverRef then | ||
− | + | unitStr = unitStr .. ' ' .. ref.coverRef | |
ref.coverRef = nil | ref.coverRef = nil | ||
end | end | ||
Строка 772: | Строка 772: | ||
show = clear | show = clear | ||
end | end | ||
− | local name, shorted = report.bigfuller( clear, badAbbr, parents ) | + | local name, shorted, overname = report.bigfuller( clear, badAbbr, parents ) |
if tilda then | if tilda then | ||
-- dictionary[name] = shorted -- 11.12.2021 | -- dictionary[name] = shorted -- 11.12.2021 | ||
end | end | ||
-- dictionary[name] = show | -- dictionary[name] = show | ||
− | return name | + | return name, shorted, overname |
end | end | ||
Строка 791: | Строка 791: | ||
local data_enum, data_ext, data_battle = {}, {}, {} | local data_enum, data_ext, data_battle = {}, {}, {} | ||
local parents = {} | local parents = {} | ||
− | title = unitfuller( args[1], nil, parents ) | + | local overname |
+ | title, _, overname = unitfuller( args[1], nil, parents, true ) | ||
data_enum[1] = { | data_enum[1] = { | ||
-- en = eN, | -- en = eN, | ||
Строка 860: | Строка 861: | ||
end | end | ||
− | if args['дополнение'] then | + | if args['дополнение'] or overname then |
data_enum[1].ext = true | data_enum[1].ext = true | ||
+ | if overname and args['дополнение'] then | ||
+ | overname = overname .. '<br>' | ||
+ | end | ||
local code = enumEncode['прицеп'] | local code = enumEncode['прицеп'] | ||
locno = locno + 1 | locno = locno + 1 | ||
Строка 869: | Строка 873: | ||
locno = locno, | locno = locno, | ||
event = code, | event = code, | ||
− | ref = args['дополнение'], | + | ref = ( overname or '' ) .. ( args['дополнение'] or '' ), |
} ) | } ) | ||
end | end | ||
Строка 910: | Строка 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, | ||
Строка 918: | Строка 932: | ||
event = way, | event = way, | ||
start = date, | start = date, | ||
− | ref = | + | ref = unitref, |
} ) | } ) | ||
end | end | ||
Строка 945: | Строка 959: | ||
for _, monotarget in ipairs( multitarget ) do | for _, monotarget in ipairs( multitarget ) do | ||
locno = locno + 1 | 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, { | table.insert( data_ext, { | ||
-- en = eN, | -- en = eN, | ||
Строка 950: | Строка 974: | ||
porno = porno, | porno = porno, | ||
locno = locno, | locno = locno, | ||
− | unit = | + | unit = fullunit, |
event = way, | event = way, | ||
start = date, | start = date, | ||
− | ref = | + | ref = unitref, |
} ) | } ) | ||
end | end | ||
Строка 1008: | Строка 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 ) |
Текущая версия на 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