Модуль: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

return s