Модуль:Новый персонаж
Перейти к навигации
Перейти к поиску
Для документации этого модуля может быть создана страница Модуль:Новый персонаж/doc
local p = {}
tools = require 'Module:Tools'
global = mw.ext.luaglobal;
local cq = mw.ext.cargo.query
local collect = require 'Module:Collect'
local function pageInCargo( name )
local query = cq( 'designations_journal',
'_pageName',
{ where = 'person = "' .. name .. '"' }
)
for i, v in ipairs( query ) do
query[i] = v._pageName
end
local query1 = cq( 'ranks_journal',
'_pageName',
{ where = 'person = "' .. name .. '"' }
)
for _, v in ipairs( query1 ) do
query[#query+1] = v._pageName
end
local query1 = cq( 'prizes_journal',
'_pageName',
{ where = 'person = "' .. name .. '"' }
)
for _, v in ipairs( query1 ) do
query[#query+1] = v._pageName
end
local query1 = cq( 'mention_journal',
'_pageName',
{ where = 'person = "' .. name .. '"' }
)
for _, v in ipairs( query1 ) do
query[#query+1] = v._pageName
end
table.sort( query )
local i, v = 1, nil
while i <= #query do
if query[i] == v then
table.remove( query, i )
else
v = query[i]
i = i + 1
end
end
return query
end
-- Побочный эффект :-)
local refErr = {}
local fpart, iopart, index, fioPattern
local hasMinus, isPattern, hasIndex, hasEndPoint
function p.anal( original )
local name = original
local out = {}
if string.sub( name, -4, -1 ) == ' (-)' then
hasMinus = true
name = string.sub( name, 1, -5 )
else
index = mw.ustring.match( name, ' (%([IVX]+%))$' )
if index then
name = string.sub( name, 1, -2 - string.len( index ) )
hasIndex = true
end
end
name = mw.ustring.gsub( name, '%.%.%.([^%.])', '#\1' )
name = mw.ustring.gsub( name, '%.%.%.$', '#' )
if string.match( name .. ' ', '[,#%.][^ ]' ) then
refErr[#refErr+1] = '<p class="error">После запятой, точки и многоточия пробелы обязательны!</p>'
name = mw.ustring.gsub( name, '([,#%.])([^ ])', '%1 %2' )
end
if string.sub( name, -1, -1) == '?' then
hasEndPoint = true
name = string.sub( name, 1, -2 )
end
fpart, iopart = string.match( name, '^([^,]+), (.+)$' )
if not fpart then
fpart = name
iopart = '#'
isPattern = true
elseif string.match( name, '[#%.]' ) then
isPattern = true
end
fioPattern = fpart .. ', ' .. string.gsub( iopart, '[#%.]', '%%' )
--[[
if not string.match( name, ',' ) then
isPattern = true
pattern = name .. ', %'
elseif string.match( name, '%.' ) then
isPattern = true
pattern = mw.ustring.gsub( name, '%.', '%%' )
else
pattern = name
end
if string.sub( pattern, -1, -1 ) ~= '%' then
pattern = pattern .. ' %'
end
--]]
end
function p.existsPage( name, index )
return mw.title.new( name .. ' ' .. (index or ''), 0 ).exists
end
function p.searchFio( name, index, isPattern )
if index then
index = ' AND disambig="' .. index .. '"'
else
index = ''
end
if isPattern then
name = 'name LIKE "' .. name .. '"'
else
name = 'name="' .. name .. '"'
end
local query = cq( 'names', '_pageName, name, disambig',
{ where = name .. index, limit = 11, orderBy = 'name, disambig' } )
return query
end
--[==[
Упрощенный аналог Collect.dbtable для работы с таблицей names_table
Пока не выкидываем лишее — например, перебор gFio
--]==]
local function collectNames( gFio )
local where = {}
local tmp
for _, fio in ipairs( gFio ) do
tmp = 'lastN="' .. fio.l .. '"'
if fio.f ~= '' then
tmp = tmp .. ' AND (firstN IS NULL OR firstN LIKE "' .. mw.ustring.sub( fio.f, 1, 1 ) .. '%")'
end
if fio.m ~= '' then
tmp = tmp .. ' AND (middleN IS NULL OR middleN LIKE "' .. mw.ustring.sub( fio.m, 1, 1 ) .. '%")'
end
if fio.d and fio.d ~= '(*)' then -- для (*) все соответствуют
tmp = tmp .. ' AND (disambig IS NULL OR disambig="' .. fio.d .. '")'
end
where[#where+1] = tmp
end
where = table.concat( where, ' OR ' )
local query = tools.cq( 'names_table', '_pageName, lastN, firstN, middleN, disambig', { where = where, limit = 1001 } )
-- do return query end
local flen, mlen, fcmp, mcmp
local fdb, mdb
local eqCount = 0
for _, row in ipairs( query ) do
fdb, mdb = row.firstN or '', row.middleN or ''
flen, mlen = string.len( fdb ), string.len( mdb )
for _, fio in ipairs( gFio ) do
if ( row.disambig == ( fio.d or '' ) or fio.d == '(*)' ) and fio.f == fdb and fio.m == mdb then
row['#eq'] = true
elseif row.disambig~='' and fio.d and row.disambig ~= fio.d then
-- не подходит
else
fcmp, mcmp = math.min( flen, string.len( fio.f ) ), math.min( mlen, string.len( fio.m ) )
if string.sub( fio.f, 1, fcmp ) == string.sub( fdb, 1, fcmp )
and string.sub( fio.m, 1, mcmp ) == string.sub( mdb, 1, mcmp ) then
row['#ap'] = true
end
end
end
if row['#eq'] or row['#ap'] then
eqCount = eqCount + 1
end
end
-- итого у нас в query готовая выборка, где у некоторых строк стоят флаги #eq и #ap
return query, eqCount
end
local function namesDisplay( namesQuery, namesCount )
if namesCount == 0 then
return '<p class="nkvd-no-names">Отсутствуют соответствующие условиям персоналии.</p>'
end
local out = {}
for _, row in ipairs( namesQuery ) do
if row['#eq'] or row['#ap'] then
local person, i, o = row.lastN, row.firstN, row.middleN
if i ~= '' or o ~= '' then
person = person .. ', '
if i == '' then
i = '...'
elseif mw.ustring.len( i ) == 1 then
i = i .. '.'
end
person = person .. i
if o ~= '' then
if mw.ustring.len( o ) == 1 then
o = o .. '.'
end
person = person .. ' ' .. o
end
end
if row.disambig ~= '' then
person = person .. ' <span class="nkvd-idx">' .. row.disambig .. '</span>'
end
out[#out+1] = row._pageName .. '|' .. person
end
end
return '[[' .. table.concat( out, ']] • [[' ) .. ']]'
end
p[''] = function ( frame )
local args = frame.args
local redlink, creatype = args[1], args [2]
local page = mw.title.getCurrentTitle()
local original = page.text
-- frame:callParserFunction{ name = 'DISPLAYTITLE', args = original .. ' ntcn' }
local out = {}
local fio_l, fio_f, fio_m, fio_d, fio_warn, fio_base = tools.splitName( original, true )
if not fio_l then
return '<div class=nkvd-error><p><big><b>Не удалось разобрать заголовок страницы.</b></big></p>' .. fio_f .. '</div>'
end
local tmp, errorpage
for _, warn in ipairs( fio_warn ) do
errorpage = tmp or string.sub( warn, 1, 1 ) ~= ' '
out[#out+1] = '<p class=error>' .. warn .. '</p>'
end
if errorpage then
out[#out+1] = '<div class=nkvd-error>Для продолжения работы исправьте ссылку и вновь вызовите эту страницу.</div>'
elseif #fio_warn ~= 0 then
out[#out+1] = '<p>При необходимости исправьте ссылку и вновь вызовите эту страницу.</p>'
end
local nsQuery, namesakes, ns0disambig = {}, {}
if not errorpage then
local where = 'lastN="' .. fio_l .. '"'
if fio_f == '' then
where = where .. ' AND firstN IS NULL'
else
where = where .. ' AND firstN="' .. fio_f ..'"'
end
if fio_m == '' then
where = where .. ' AND middleN IS NULL'
else
where = where .. ' AND middleN="' .. fio_m ..'"'
end
nsQuery = cq( 'names_table', '_pageName, lastN, firstN, middleN, disambig', { where = where } )
for _, row in ipairs( nsQuery ) do
namesakes[row.disambig] = row
end
if not namesakes[''] then
tmp = mw.title.new( fio_base ):getContent()
ns0disambig = mw.ustring.match( tmp or '', '%{%{%s*[Нн]еоднозначность' )
-- out[#out+1] = '\n\n\n«««' .. (tmp or '—') .. '»»»\n\n\n'
end
end
if fio_d == '(*)' then
out[#out+1] = '<div class=nkvd-error><b>Ссылки, созданные шаблоном «[[Шаблон:Персона*|персона*]]»'
.. ' («[[Шаблон:Упоминание*|упоминание*]]»), не должны использоваться для создания страниц.</b><br>'
if not errorpage then
if #nsQuery == 0 and not ns0disambig then
out[#out+1] = 'Страницы-тезки отсутствуют в базе, для создания страницы достаточно'
.. ' убрать «*» из названия шаблона и вновь вызвать данную страницу'
elseif ns0disambig then
out[#out+1] = 'Уже существует [[' .. fio_base .. '|страница разрешения неоднозначности]]'
.. ' по этому имени, для создания страницы персоналии нужно убрать «*» из названия шаблона'
.. ' и добавить к имени персоналии первый свободный (или нужный из имеющихся) номер тезки'
elseif namesakes[''] then
if #nsQuery > 1 then
out[#out+1] = '<big>Существующий набор страниц тезок находится в непредусмотренном состоянии.'
.. ' Требуется компетентное вмешательство!</big>'
else
out[#out+1] = 'Сейчас существует единственная персоналия с таким именем,'
.. ' и создание тезки потребует усилий. Прежде всего потребуется убрать «*»'
.. ' из названия шаблона, вслед за именем персоналии поставить через пробел «(II)»'
.. ' и вновь перейти по ссылке сюда'
end
end
end
out[#out+1] = '</div>'
errorpage = true
end
local prizesQuery, prizesCount = collect.dbtable( { { l=fio_l, f=fio_f, m=fio_m, d=fio_d } },
'prizes_table',
'cDate, cDate__precision, _pageName, reference, prize, prizeNumber, origin, alias, podvig, nLast, nFirst, nMiddle, nDisambig, nPrecision',
nil )
local ranksQuery, ranksCount = collect.dbtable( { { l=fio_l, f=fio_f, m=fio_m, d=fio_d } },
'ranks_table',
'cDate, cDate__precision, _pageName, reference, rank, origin, alias, nLast, nFirst, nMiddle, nDisambig, nPrecision',
nil )
local designationsQuery, designationsCount = collect.dbtable( { { l=fio_l, f=fio_f, m=fio_m, d=fio_d } },
'designations_table',
'cDate, cDate__precision, _pageName, reference, unit, position, segment, origin, article, dismissal_type, formula, alias, nLast, nFirst, nMiddle, nDisambig, nPrecision',
nil )
local mentionsQuery, mentionsCount = collect.dbtable( { { l=fio_l, f=fio_f, m=fio_m, d=fio_d } },
'mentions_table',
'cDate, cDate__precision, _pageName, reference, comment, nLast, nFirst, nMiddle, nDisambig, nPrecision',
nil )
local namesQuery, namesCount = collectNames( { { l=fio_l, f=fio_f, m=fio_m, d=fio_d } } )
if redlink then
out[#out+1] = '<div style="width: 100%; box-sizing: border-box; border:1px dotted black; background-color: #f8f4ff; padding: 0.5em; margin-bottom: 0.5em;">'
else
out[#out+1] = '__NOTOC__\n<h2>Справочная информация</h2><div>'
end
out[#out+1] = '<table style="width: 100%;"><tr>'
if namesCount == 0 then
out[#out+1] = '<td style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">Нет страниц персоналий с таким именем</td>'
else
out[#out+1] = '<td class="mw-customtoggle-names" style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">[[#0|Список персоналий]]</td>'
end
if designationsCount == 0 then
out[#out+1] = '<td style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">Нет записей о службе</td>'
else
out[#out+1] = '<td class="mw-customtoggle-designations" style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">[[#0|Записи о службе]]</td>'
end
if ranksCount == 0 then
out[#out+1] = '<td style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">Нет записей о званиях</td>'
else
out[#out+1] = '<td class="mw-customtoggle-ranks" style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">[[#0|Записи о званиях]]</td>'
end
if prizesCount == 0 then
out[#out+1] = '<td style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">Нет записей о награждениях</td>'
else
out[#out+1] = '<td class="mw-customtoggle-prizes" style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">[[#0|Записи о награждениях]]</td>'
end
if mentionsCount == 0 then
out[#out+1] = '<td style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">Нет иных упоминаний</td>'
else
out[#out+1] = '<td class="mw-customtoggle-mentions" style="width: 20%; border:4px solid #ccc; padding: 4px; text-align: center">[[#0|Иные упоминания]]</td>'
end
out[#out+1] = '</tr></table>'
if namesCount ~= 0 then
out[#out+1] = '<div id="mw-customcollapsible-names" class="mw-collapsible" style="border:1px solid #ccc; box-sizing: border-box; padding: 3px; margin-bottom: 0.5em;">'
out[#out+1] = '<div class="mw-customtoggle-names" style="float: right; margin: 0 0.5em; font-size: 120%; font-weight: bold;">[[#0|×]]</div>'
out[#out+1] = '<h3>Страницы персоналий</h3>'
out[#out+1] = namesDisplay( namesQuery, namesCount )
out[#out+1] = mw.getCurrentFrame():extensionTag( 'references' )
out[#out+1] = '</div>'
end
if designationsCount ~= 0 then
out[#out+1] = '<div id="mw-customcollapsible-designations" class="mw-collapsible mw-collapsed" style="display: none; border:1px solid #ccc; box-sizing: border-box; padding: 3px; margin-bottom: 0.5em;">'
out[#out+1] = '<div class="mw-customtoggle-designations" style="float: right; margin: 0 0.5em; font-size: 120%; font-weight: bold;">[[#0|×]]</div>'
out[#out+1] = '<h3>Записи о прохождении службы</h3>'
out[#out+1] = require ('Модуль:Отображение назначений').display( designationsQuery, designationsCount, true )
out[#out+1] = mw.getCurrentFrame():extensionTag( 'references' )
out[#out+1] = '</div>'
end
if ranksCount ~= 0 then
-- do return (mw.dumpObject(ranksQuery )) end
out[#out+1] = '<div id="mw-customcollapsible-ranks" class="mw-collapsible mw-collapsed" style="display: none; border:1px solid #ccc; box-sizing: border-box; padding: 3px; margin-bottom: 0.5em;">'
out[#out+1] = '<div class="mw-customtoggle-ranks" style="float: right; margin: 0 0.5em; font-size: 120%; font-weight: bold;">[[#0|×]]</div>'
out[#out+1] = '<h3>Записи о званиях</h3>'
out[#out+1] = require ('Модуль:Отображение званий').display( ranksQuery, ranksCount, true )
out[#out+1] = mw.getCurrentFrame():extensionTag( 'references' )
out[#out+1] = '</div>'
end
if prizesCount ~= 0 then
out[#out+1] = '<div id="mw-customcollapsible-prizes" class="mw-collapsible mw-collapsed" style="display: none; border:1px solid #ccc; box-sizing: border-box; padding: 3px; margin-bottom: 0.5em;">'
out[#out+1] = '<div class="mw-customtoggle-prizes" style="float: right; margin: 0 0.5em; font-size: 120%; font-weight: bold;">[[#0|×]]</div>'
out[#out+1] = '<h3>Записи о награждениях</h3>'
out[#out+1] = require ('Модуль:Отображение наград').display( prizesQuery, prizesCount, true )
out[#out+1] = mw.getCurrentFrame():extensionTag( 'references' )
out[#out+1] = '</div>'
end
if mentionsCount ~= 0 then
out[#out+1] = '<div id="mw-customcollapsible-mentions" class="mw-collapsible mw-collapsed" style="display: none; border:1px solid #ccc; box-sizing: border-box; padding: 3px; margin-bottom: 0.5em;">'
out[#out+1] = '<div class="mw-customtoggle-mentions" style="float: right; margin: 0 0.5em; font-size: 120%; font-weight: bold;">[[#0|×]]</div>'
out[#out+1] = '<h3>Иные упоминания</h3>'
out[#out+1] = require ('Модуль:Отображение упоминаний').display( mentionsQuery, mentionsCount, true )
out[#out+1] = mw.getCurrentFrame():extensionTag( 'references' )
out[#out+1] = '</div>'
end
--[==[
fio_d = '' / '(*)' / '(N)'
db[''] = нет / есть
page[''] = нет / неодн. / страница
--]==]
out[#out+1] = require( 'Module:Toolbar' )( fio_l, fio_f, fio_m )
do
out[#out+1] = '</div>'
return table.concat( out, '\n' )
end
p.anal( original )
-- простая красная ссылка
if not (hasIndex or hasMinus or isPattern or hasEndPoint) then
-- на всякий случай проверяем отсутствие страницы с индексом «(I)»
local children = p.searchFio( name )
if #children ~= 0 or p.existsPage( name, '(I)' ) then
refErr[#refErr+1] = '<p class="error">Эта страница должна быть страницей разрешения неоднозначностей.</p>'
end
end
if index == '(II)' then -- предполагаем создание первого тезки
-- Предлагаемые шаги.
-- 1) измените все существующие ссылки c root на root-1
-- 2) переименуйте root в root-1
-- 3) измените содержимое root
end
return frame.args[1]
end
while false do
local u = mw.text.split( name, ' ' )
local idx = u[#u]
if not string.match( idx, '^%([IVX]+%)$' ) then --false and
return tools.errorMsg( 'Новый тезка',
'В заголовке страницы отсутствует номер тезки',
'Этот шаблон помогает создавать страницы для тезок существующих в справочнике'
.. ' персонажей. Названия создаваемых для тезок страниц имеют вид'
.. ' «Фамилия, Имя Отчество (N)», где N — записанный римскими цифрами'
.. ' порядковый номер тезки. Если для нужного вам имени уже существует'
.. ' более одного тезки (то есть уже существуют страницы с номерами в'
.. ' названии), то вам не требуется ничего специального, достаточно'
.. ' завести страницу с очередным номером. Если же в справочнике'
.. ' есть единственный тезка вашего персонажа, то создайте страницу'
.. ' с названием «Фамилия, Имя Отчество (II)» и для получения подсказок'
.. ' поместите там текст «{{ новый тезка }}»'
)
end
local out = {}
if idx ~= '(II)' then
out[#out+1] = 'Обычно шаблон {{ новый тезка }} требуется применяется для'
.. ' создания страницы с индексом (II). <b>Вы уверены,'
.. ' что хотите создать страницу с индексом ' .. u[#u] .. '?</b>\n'
end
u[#u] = nil
-- u = { 'Берия, Лаврентий Павлович' }
local rootPage = mw.title.new( table.concat( u, ' ' ), 0 )
local root = rootPage.fullText
local alterPage = mw.title.new( root .. ' (I)', 0 )
-- Предлагаемые шаги.
-- 1) измените все существующие ссылки c root на root-1
-- 2) переименуйте root в root-1
-- 3) измените содержимое root
-- обзираем ситуацию. Убеждаемся, что root — это пока нормальная страница,
-- а root-1 не существует
local rootIsDisambig, rootExists, alterExists
rootExists = rootPage.exists
local oldContent = rootPage:getContent()
rootIsDisambig = mw.ustring.match( oldContent, '%{%{%s*неоднозначность' )
alterExists = alterPage.exists
query = pageInCargo( root )
if #query ~= 0 then
out[#out+1] = 'Ссылка на существующую страницу «[[' .. root .. ']]» используется в шаблонах на следующих страницах:<ul>'
for _, v in ipairs( query ) do
out[#out+1] = '<li>[[' .. v .. ']] [' .. tostring( mw.uri.fullUrl( v, { action = 'edit'} ) ) .. ' <i class="fa fa-pencil"></i>]</li>'
end
out[#out+1] = '</ul>\n'
end
out[#out+1] = require( 'Модуль:Отображение назначений').display( 'person="' .. root ..'"', true )
return table.concat( out, '\n' )
-- local root = mw.title.new( table.concat( u, ' ' ), 0 )
-- local here = mw.text.unstripNoWiki( frame:preprocess( '{{Special:WhatLinksHere/' .. root.fullText ) )
-- return string.len(here) .. '---' .. mw.ustring.len(here) .. '---\n' .. here
end
return p