Модуль:BEED
Для документации этого модуля может быть создана страница Модуль:BEED/Документация
local s = {}
local roman = require('Module:RomanNumber')
--[[ Функция производит разбор строки вида <номер полутома>/<номер страницы>[/<число страниц - 1>]
Возвращает объект с тремя полями:
volume - номер полутома (от 1 до 86)
page - номер страницы тома, на которой начинается статья
numpages - число страниц - 1
]]
function s.parseVolumeStr(s_data)
if s_data == nil or s_data == '' then
return nil
end
local x = mw.text.split(s_data, "/")
if #x < 2 or #x > 3 then
return nil
end
local result = {volume = tonumber(x[1]), page = tonumber(x[2]), numpages = 0}
if #x == 3 then
result.numpages = tonumber(x[3]) -- число страниц - 1
end
return result
end
function parseStr(s_data)
local n_volume = nil
local n_page = nil
local n_numpages = nil
if s_data:find("/") then
local x = mw.text.split(s_data, "/")
n_volume = tonumber(x[1]) -- номер полутома (от 1 до 86)
n_page = tonumber(x[2]) -- номер страницы тома, на которой начинается статья
n_numpages = tonumber(x[3]) -- число страниц - 1
if n_numpages == nil then
n_numpages = 0
end
end
return n_volume, n_page, n_numpages
end
function s.transclude (frame, s_base, s_add, s_section, b_old_spell)
local a = {}
a[1] = s.parseVolumeStr(s_base)
a[2] = s.parseVolumeStr(s_add)
local x = {}
for i = 1, 2 do
local part = a[i]
if part ~= nil then
local s_part = nil
for n_page = part.page, part.page + part.numpages do
local s_template = frame:expandTemplate { title = 'ЭСБЕ/Страница', args = {part.volume, n_page, section = s_section} }
if s_part ~= nil and s_part ~= "" then
s_part = s_part .. " " .. s_template
else
s_part = s_template
end
end
x[i] = s_part
else
x[i] = nil
end
end
local result = nil
if x[1] ~= nil and x[2] ~= nil then
if b_old_spell then
result = x[1] .. '\n\n== Дополненіе. ==\n' .. x[2]
else
result = x[1] .. '\n\n== Дополнение ==\n' .. x[2]
end
elseif x[1] ~= nil then
result = x[1]
elseif x[2] ~= nil then
result = x[2]
end
return result
end
-- Возвращает номер страницы в скане по номеру полутома и страницы
function getScanPage(n_volume, n_page)
assert((n_volume >= 1) or (n_volume <= 86), 'Неверный номер полутома')
assert(n_page ~= nil, 'Не задан номер страницы')
local scans = mw.loadData ('Module:BEED/scans')
--[[ Вот этот код почему-то не работает из-за того, что next(items) не возвращает первого элемента
local items = scans[n_volume]
local prev_key = nil
local prev_item = nil
local curr_key, curr_item = next(items) -- первый элемент коллекции
-- assert(curr_item ~= nil, 'пустой items')
while curr_item ~= nil do
mw.log('curr_item[1] = '..curr_item[1])
mw.log('curr_item[2] = '..curr_item[2])
if n_page < curr_item[1] then
if prev_item ~= nil then
return prev_item[2] + n_page - prev_item[1]
end
break
end;
prev_item = curr_item
prev_key = curr_key
curr_key, curr_item = next(items, prev_key) -- следующий элемент коллекции
end
]]
local prev_item = nil
local curr_key = nil
local curr_item = nil
for curr_key, curr_item in ipairs(scans[n_volume]) do
if n_page < curr_item[1] then
if prev_item ~= nil then
return prev_item[2] + n_page - prev_item[1]
end
break
end;
prev_item = curr_item
end
return nil
end
-- Функция для вызова getScanPage()
function s.get_scan_page (frame)
local n_volume = tonumber(frame.args[1])
local n_page = tonumber(frame.args[2])
return tostring(getScanPage(n_volume, n_page))
end
-- Возвращает номер словника по имени статьи
function s.getListNum(s_name)
local lists = mw.loadData('Module:BEED/lists')
local prev_item = nil
local curr_key = nil
local curr_item = nil
for curr_key, curr_item in ipairs(lists) do
if s_name < curr_item.from then
if prev_item ~= nil then
return prev_item.key
end
break
end;
prev_item = curr_item
end
return nil
end
--По номеру полутома возвращает номер тома (I, Ia, II, IIа и т. д.) и имя соотв. файла со сканом
function getVolumeData(n_volume)
assert((n_volume >= 1) or (n_volume <= 86), 'Неверный номер полутома')
local s_volume_name = nil
local s_file_name = nil
local b_even = (n_volume%2 == 0)
if n_volume >= 83 then
local n_vol_num = math.floor((n_volume - 81)/2) -- номер дополнительного тома (1 или 2)
s_volume_name = "доп. "..roman.toRomanNumber(n_vol_num)
s_file_name = "Encyclopedicheskii slovar dopoln tom "..tostring(n_vol_num)
if b_even then
s_volume_name = s_volume_name.."a"
s_file_name = s_file_name.." a"
end
s_file_name = s_file_name..".djvu"
else
local n_vol_num = math.floor((n_volume + 1)/2) -- номер основного тома (от 1 до 41)
s_volume_name = roman.toRomanNumber(n_vol_num)
s_file_name = "Encyclopedicheskii slovar tom "..tostring(n_vol_num)
if b_even then
s_volume_name = s_volume_name.."a"
s_file_name = s_file_name.." a"
end
s_file_name = s_file_name..".djvu"
end
return s_volume_name, s_file_name
end
-- Функция по номеру полутома возврашающая его имя
-- Используется в Шаблон:ЭСБЕ/Номер тома
function s.get_volume_name(frame)
local n_volume = tonumber(frame.args[1])
local s_volume_name, s_file_name = getVolumeData(n_volume)
return s_volume_name
end
-- Функция по номеру полутома возврашающая имя файла со сканом
-- Используется в Шаблон:ЭСБЕ/Скан2
function s.get_file_name(frame)
local n_volume = tonumber(frame.args[1])
local s_volume_name, s_file_name = getVolumeData(n_volume)
return s_file_name
end
function s.djvu(data)
local n_volume, n_page, n_numpages = parseStr(data)
local s_volume_name, s_file_name = getVolumeData(n_volume)
return s_file_name
end
-- Функция по номеру полутома и номеру страницы возврашающая страницу файла со сканом
-- Используется в Шаблон:ЭСБЕ/Страница
function s.get_file_name_page(frame)
local n_volume = tonumber(frame.args[1])
local n_page = tonumber(frame.args[2])
local s_volume_name, s_file_name = getVolumeData(n_volume)
local n_scan_page = getScanPage(n_volume, n_page)
return s_file_name.."/"..tostring(n_scan_page)
end
--[[
function s.djvupage (frame, data)
local a = data or frame.args[1]
local page, _, djvu = getScanData (a)
return djvu .. '/' .. page
end
]]
-- Функция, реализующая Шаблон:ЭСБЕ/Скан и Шаблон:ЭСБЕ/Статья
function s.scan (frame)
local n_volume, n_page, n_numpages
if string.find ( frame.args[1], "%d+/%d+" ) then
-- формат вызова: один параметр вида <номер полутома>/<номер страницы>/<число страниц - 1> (как в Шаблон:ЭСБЕ/Статья)
n_volume, n_page, n_numpages = parseStr(frame.args[1])
else
-- формат вызова: три параметра (как в Шаблон:ЭСБЕ/Скан)
n_volume = tonumber(frame.args[1])
n_page = tonumber(frame.args[2])
n_numpages = tonumber(frame.args[3])
end
if n_volume == nil or n_volume < 1 or n_volume > 86 then return end
if n_page == nil then return end
if n_numpages == nil then
n_numpages = 0
end
-- Определяем страницу в скане
local n_scan_page = getScanPage(n_volume, n_page)
-- Определяем имя файла со сканами
local s_volume_name, s_file_name = getVolumeData(n_volume)
local s_suffix = ""
if n_page > 1000 then
n_page = n_page - 1000
s_suffix = " (Россия)"
end
local s_pages
if n_numpages > 0 then
s_pages = tostring(n_page).."—"..tostring(n_page + n_numpages)..s_suffix
else
s_pages = tostring(n_page)..s_suffix
end
if n_scan_page == nil then
return "<span class='plainlinks' style='white-space:nowrap'>''"..s_volume_name..", "..s_pages.."''</span>"
else
return "<span class='plainlinks' style='white-space:nowrap'>[[File:Fictional page.svg|x16px|link=]] ["..frame:callParserFunction{ name = 'fullurl', args = {'File:'..s_file_name, page = tostring(n_scan_page)}}.." ''"..s_volume_name..", "..s_pages.."'']</span>"
end
end
-- Для шаблона ЭСБЕ/Дубль с поддержкой новых словников
function s.duplicate( frame )
--local pagename = mw.title.getCurrentTitle().text
--local PRS = pagename:match( "/ДО$" ) or ""
local args = mw.getCurrentFrame():getParent().args
local articles, links, tlinks = {}, {}, {}
local function roman(n) return require("Модуль:Math").rn(n) end
local function link(a,v,p) return '* [[ЭСБЕ/'..a..'|'..a..']] ('..v..', '..p..')' end
local function tlink(a,v,p) return '* {{ЭСБЕ/Ссылка|'..a..'|'..a..'}} ('..v..', '..p..')' end
local function articles_add (a)
for _, s in ipairs(a) do
s = mw.text.trim(s)
if s and s ~= '' and not s:find('^%d') then table.insert(articles, s) end
end
end
articles_add ({ args['статья'], args['статья1'], args['статья2'] })
if #articles == 0 then articles_add ({ args[1], args[2], args[3] }) end
if #articles == 0 then return end
local esbe = mw.loadData( 'Модуль:Отексте/ЭСБЕ' )
local root, list, list2 = esbe.main.listroot.default, esbe.main.listnum, esbe.supplement.listnum
for i, name in ipairs ( articles ) do
-- нормализация названия статьи для поиска
local sname = mw.ustring.gsub ( name, '[Йй]', 'и~' )
sname = mw.ustring.toNFD ( sname )
sname = mw.ustring.gsub ( mw.ustring.gsub ( sname, "[^%w,(~]", "" ), "^%p", "" )
sname = mw.ustring.gsub ( sname, 'и~', 'й' )
local lang = mw.language.new (mw.language.getContentLanguage().code)
sname = lang:ucfirst ( lang:lc (sname) )
mw.logObject(sname,'sname')
-- отбор словников
local toc = { t = {} }
function toc:add(tab)
for i, _ in ipairs ( tab ) do
if sname >= tab[i][1] and ( tab[i+1] == nil or sname < tab[i+1][1] ) then
for _, number in ipairs ( tab[i][2] ) do table.insert ( self.t, number ) end
break
end
end
end
toc:add(list)
toc:add(list2)
mw.logObject(toc.t,'toc.t')
--if #toc.t == 0 then return end
-- поиск в словниках
for _, item in ipairs(toc.t) do
local title = mw.title.new( root .. item )
if title then
text = title:getContent()
if text then
local pat = "{{%s*Статья в словнике%s*|%s*" .. escapePattern( name ) .. "%s*|[^|{}]+|%s*([^|{}]+)[^{}]*}}"
local foundstr = mw.ustring.match( text, pat )
if foundstr then
foundstr = foundstr:gsub( "^(%d+).*$", "%1" )
local prefix = ''
local vol = item:gsub( "^(%d+).*$", "%1" ); vol = tonumber(vol)
if vol > 82 then vol = vol - 82; prefix = 'доп. ' end
local rvol = prefix..roman((math.floor(vol+1)/2)); if vol % 2 == 0 then rvol = rvol .. 'a' end
links[i] = link( name, rvol, foundstr )
tlinks[i] = tlink( name, rvol, foundstr )
break
end
end
end
end
-- если не найдено
links[i] = links[i] or '* {{ЭСБЕ/Ссылка|' .. name .. '|' .. name .. '}}'
tlinks[i] = tlinks[i] or links[i]
end
local result = table.concat(links,'\n')
if #tlinks > 0 then result = result .. frame:preprocess('\n{{Версии|\n' .. table.concat(tlinks,'\n') ..'\n|title=Другие версии}}') end
if #result > 0 then result = result .. '[[Категория:ЭСБЕ:Дубли статей]]' end
return result
end
-- escape certain characters in regex patterns
function escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end
return s