Модуль:PersTools
Перейти к навигации
Перейти к поиску
Для документации этого модуля может быть создана страница Модуль:PersTools/doc
local perstools = {}
function perstools.makePersonLink( row )
local person, i, o, d = row.nLast, row.nFirst, row.nMiddle, row.nDisambig
if i ~= '' or o ~= '' then
person = person .. ', '
if ( i or '' ) == '' then
-- i = '...'
i = '-.'
elseif mw.ustring.len( i ) == 1 then
i = i .. '.'
end
person = person .. i
if ( o or '' ) ~= '' then
if mw.ustring.len( o ) == 1 then
o = o .. '.'
end
person = person .. ' ' .. o
end
end
if ( d or '' ) ~= '' then
local ds = d
-- if d == '(*)' then
-- ds = '<i class="fa fa-asterisk fa-lg"></i>'
-- end
return '[[' .. person .. ' ' .. d .. '|'
.. person .. ' <span class="nkvd-idx">' .. ds .. '</span>]]'
end
return '[[' .. person .. ']]'
end
local function altLast( f, similarTable )
local alt = { f }
local notAlt = {}
local function addSimilar( str )
if similarTable.simLast[str] then
for _, sim in ipairs( similarTable.lastArray[similarTable.simLast[str]] ) do
table.insert( alt, sim )
end
end
if similarTable.notLast[str] then
table.insert( notAlt, similarTable.notLast[str] )
end
end
-- разбираем двойную фамилию или предполагаем, что фамилия может быть двойной
local twin, twin2 = string.match( f, '(.+)%-(.+)' )
if twin then
table.insert( alt, twin )
table.insert( alt, twin2 )
table.insert( alt, twin2 .. '-' .. twin )
addSimilar( twin )
addSimilar( twin2 )
else
addSimilar( f )
end
local alt2 = {}
for _, f in ipairs( alt ) do
local tail = mw.ustring.sub( f, -4, -1 )
local altTails = similarTable.tails[tail]
if not altTails then
tail = mw.ustring.sub( f, -3, -1 )
altTails = similarTable.tails[tail]
if not altTails then
tail = mw.ustring.sub( f, -2, -1 )
altTails = similarTable.tails[tail]
if not altTails then
tail = mw.ustring.sub( f, -1, -1 )
altTails = similarTable.tails[tail]
if not altTails then
tail = ''
altTails = similarTable.tails['']
end
end
end
end
local body = mw.ustring.sub( f, 1, - mw.ustring.len( tail ) - 1 )
local subst = mw.ustring.gsub( body, '[аоеийышщШЩБВ]', { ['а'] = '[ао]', ['о'] = '[ао]', ['е'] = '[еи]', ['и'] = '[еиый]', ['ы'] = '[ыие]', ['й'] = '[еий]',
['ш'] = '[шщ]', ['щ'] = '[шщ]', ['Ш'] = '[ШЩ]', ['Щ'] = '[ШЩ]', ['Б'] = '[БВ]', ['В'] = '[БВ]', } )
subst = mw.ustring.gsub( subst, '[дт]с', 'ц' )
subst = mw.ustring.gsub( subst, 'лл', 'л' )
subst = mw.ustring.gsub( subst, 'мм', 'м' )
subst = mw.ustring.gsub( subst, 'нн', 'н' )
subst = mw.ustring.gsub( subst, 'сс', 'с' )
subst = mw.ustring.gsub( subst, 'зь?м', 'Зь?М' ) -- используем то, что в Lua поиск регистро-зависимый, а в SQL нет
subst = mw.ustring.gsub( subst, '[сз]', '[сз]с?' )
subst = mw.ustring.gsub( subst, 'л', 'лл?' )
subst = mw.ustring.gsub( subst, 'м', 'мм?' )
subst = mw.ustring.gsub( subst, 'н', 'н+' )
subst = mw.ustring.gsub( subst, 'н%+ь?%[шщ%]', 'н+ь?[шщ]' )
subst = mw.ustring.gsub( subst, 'ц', '(ц|тс|дс)' )
alt2[subst .. '(' .. altTails .. ')'] = true
end
local altRes = {}
for altPtn in pairs( alt2 ) do
-- из-за этого не ловятся персонажи с ошибкой в одной из частей двойной фамилии
if twin then
table.insert( altRes, altPtn )
else
table.insert( altRes, altPtn .. '(-.+)?' )
table.insert( altRes, '(.+-)?' .. altPtn )
end
end
if next( notAlt ) then
notAlt = table.concat( notAlt, ', ' )
else
notAlt = nil
end
return altRes, notAlt
end
function perstools.searchSimilar( f, i, o )
local similarTable = require( 'Module:SimilarTable' )
local fPatterns, fExclude = altLast( f, similarTable )
if fExclude then
fExclude = ' AND fio_f NOT IN ( ' .. fExclude .. ' )'
end
local fQuery = '( fio_f RLIKE "^' .. table.concat( fPatterns, '$" OR fio_f RLIKE "^' ) .. '$" )' .. ( fExclude or '' )
local iQuery, oQuery
if ( i or '' ) ~= '' then
if string.sub( i, -1, -1 ) == '.' then
iQuery = 'fio_i LIKE "' .. string.sub( i, 1, -2 ) .. '%"'
elseif mw.ustring.len( i ) == 1 then
iQuery = 'fio_i LIKE "' .. i .. '%"'
else
-- iQuery = 'fio_i IN ( "' .. mw.ustring.sub( i, 1, 1 ) .. '","' .. table.concat( check( i, similarFirst ), '","' ) .. '" )'
iQuery = 'fio_i IN ( "' .. mw.ustring.sub( i, 1, 1 ) .. '", ' .. ( similarTable.simArray[similarTable.simFirst[i] or 0] or ( '"' .. i .. '"' ) ) .. ' )'
end
iQuery = ' AND ( fio_i IS NULL OR ' .. iQuery .. ' )'
end
if ( o or '' ) ~= '' then
if string.sub( o, -1, -1 ) == '.' then
oQuery = 'fio_o LIKE "' .. string.sub( o, 1, -2 ) .. '%"'
elseif mw.ustring.len( o ) == 1 then
oQuery = 'fio_o LIKE "' .. o .. '%"'
else
local oo = similarTable.simArray[similarTable.simMiddle[o] or 0]
if not oo then
local body = mw.ustring.match( o, '^(.-)[иеь]евич$' )
if body then
oo = '"' .. body .. 'ьевич", "' .. body .. 'иевич", "' .. body .. 'еевич"'
else
oo = '"' .. o .. '"'
end
end
oQuery = 'fio_o IN ( "' .. mw.ustring.sub( o, 1, 1 ) .. '", ' .. oo .. ' )'
end
oQuery = ' AND ( fio_o IS NULL OR ' .. oQuery .. ' )'
end
-- local where = '( fio_f IN ( "' .. table.concat( fAlt, '","' ) .. '" )' .. ( likePart or '' ) .. ' )'
local where = fQuery
.. ( iQuery or '' ).. ( oQuery or '' )
local res = mw.ext.externalData.getExternalData( { db='cargoview', from = 'aa_szr__names', data = 'fio_f, fio_i, fio_o, fio_d, page, min_date, max_date, counter', where = where, limit = 100 } )
return res
end
return perstools