Модуль:Сапраўдны нумар старонкі
Глядзі Шаблон:Сапраўдны нумар старонкі.
-- Модуль, які ідэнтыфікуе сапраўдны нумар старонкі (праз інфармацыю з
-- 'pagelist' са старонкі індэкса). Выкарыстоўваецца ў прасторы старонак
-- у калонтытуле для аўтаматычнага адлюстравання нумароў старонак.
--
-- Параметры:
-- 'калі':
-- 'цотны'/'цотная' - ігнараваць усё акрамя цотных старонак
-- 'няцотны'/'няцотная' - ігнараваць усё акрамя няцотных старонак
-- 'л' - дадаткова прычапіць кавалак тэксту злева
-- 'п' - дадаткова прычапіць кавалак тэксту справа
local p = {}
-- TODO: move books information table to another script
-- These are the starting pages of each book chapter. The last number in
-- the table is the last page +1 (a would-be start of the next nonexisting chapter).
local translated_books = {
["Прынц і жабрак (1928).pdf"] = {
{
bel_chapters = { 1, 2, 7, 15, 19, 27, 36, 39, 42, 45, 55, 60, 72, 77, 90, 102, 105, 116, 124, 129, 136, 141, 147, 150, 153, 161, 166, 177, 181, 183, 186, 192, 204, 212, 215 + 1 },
eng_chapters = { 23, 27, 37, 49, 57, 73, 89, 97, 103, 109, 123, 133, 151, 161, 179, 195, 203, 223, 237, 247, 259, 269, 281, 289, 295, 309, 317, 333, 341, 347, 353, 365, 385, 399, 401 + 1 },
prefix = ":s:en:The_Prince_and_the_Pauper/Chapter_",
subst = { ["Chapter_34"] = "Conclusion" },
}
},
["Прынц і жабрак (1940).pdf"] = {
{
bel_chapters = { 3, 4, 10, 17, 23, 32, 40, 45, 48, 50, 59, 64, 77, 81, 94, 105, 108, 120, 127, 133, 139, 143, 150, 154, 157, 164, 168, 178, 182, 184, 186, 192, 204, 212, 214 + 1 },
eng_chapters = { 23, 27, 37, 49, 57, 73, 89, 97, 103, 109, 123, 133, 151, 161, 179, 195, 203, 223, 237, 247, 259, 269, 281, 289, 295, 309, 317, 333, 341, 347, 353, 365, 385, 399, 401 + 1 },
prefix = ":s:en:The_Prince_and_the_Pauper/Chapter_",
subst = { ["Chapter_34"] = "Conclusion" },
}
},
["Востраў скарбаў.pdf"] = {
{
bel_chapters = { 3, 11, 17, 24, 31, 37, 45, 51, 57, 63, 68, 75, 82, 87, 92, 100, 105, 110, 114, 120, 126, 133, 138, 142, 146, 152, 160, 166, 174, 180, 187, 194, 200, 206, 212 + 1 },
eng_chapters = { 1, 10, 19, 28, 37, 45, 54, 61, 69, 77, 85, 94, 103, 110, 118, 128, 135, 142, 149, 158, 166, 175, 184, 191, 199, 206, 218, 227, 238, 247, 257, 267, 276, 285, 292 + 1 },
prefix = ":s:en:Treasure_Island_(1883)/Chapter_",
}
},
["Апошні з магікан.pdf"] = {
-- bel_chapters = { 3, 14, 26, 37, 51, 63, 78, 93, 108, 118, 131, 149, 165, 177, 195, 211, 228, 248, 261, 275, 290, 306, 321, 340, 357, 376, 390, 401, 416, 435, 452, 464, 482, 496 + 1 },
{
bel_chapters = { 3, 14, 26, 37, 51, 63, 78, 93, 108, 118, 131, 149, 164 + 1 },
eng_chapters = { 1, 24, 44, 64, 84, 105, 130, 156, 179, 199, 226, 256, 287 + 1 },
prefix = ":s:en:The_Last_of_the_Mohicans;_a_Narrative_of_1757/Volume_1/Chapter_"
},
{
bel_chapters = { 165, 177, 195, 211, 228, 248, 261, 275, 290, 306, 320 + 1 },
eng_chapters = { 1, 26, 58, 84, 111, 144, 171, 200, 227, 251, 276 + 1 },
prefix = ":s:en:The_Last_of_the_Mohicans;_a_Narrative_of_1757/Volume_2/Chapter_"
},
{
bel_chapters = { 321, 340, 357, 376, 390, 401, 416, 435, 452, 464, 482, 496 + 1 },
eng_chapters = { 1, 31, 58, 87, 111, 134, 157, 186, 213, 232, 266, 295 + 1 },
prefix = ":s:en:The_Last_of_the_Mohicans;_a_Narrative_of_1757/Volume_3/Chapter_"
},
},
["Домбі і сын.pdf"] = {
{
bel_chapters = { 3, 11, 19, 28, 38, 51, 67, 70, 85, 93, 101, 111, 126, 135, 153, 163, 168, 175, 189, 198, 207, 214, 229, 244, 252, 258, 270, 280, 287, 294, 303, 315, 330, 340, 350, 359, 368, 376, 384, 397, 410, 418, 429, 435, 442, 447, 456, 469, 477, 488, 500, 505, 517, 528, 535, 541, 556, 561, 569, 580, 586, 593, 597 + 1 },
eng_chapters = { 1, 8, 16, 24, 33, 45, 61, 65, 79, 88, 97, 107, 120, 129, 146, 157, 161, 169, 183, 193, 203, 211, 225, 241, 250, 257, 269, 281, 289, 297, 309, 321, 334, 343, 353, 361, 370, 378, 385, 397, 409, 417, 428, 435, 442, 449, 458, 472, 481, 494, 507, 513, 524, 536, 545, 554, 571, 577, 588, 602, 611, 620, 624 + 1 },
prefix = ":s:en:Dombey_and_Son_(1848)/Chapter_",
}
},
}
-- Calculate the length of the overlappping area of two intervals
local function calc_overlap(min_a, max_a, min_b, max_b)
if max_a <= min_b or max_b <= min_a then
return 0 -- no overlap at all
end
if min_a <= min_b and max_a >= max_b then
return max_b - min_b -- b is fully enclosed by a
end
if min_b <= min_a and max_b >= max_a then
return max_a - min_a -- a is fully enclosed by b
end
if max_a >= min_b and max_a <= max_b then
return max_a - min_b -- partial overlap, a is on the left side
end
if max_b >= min_a and max_b <= max_a then
return max_b - min_a -- partial overlap, b is on the left side
end
end
-- Find the most suitable English page, assuming that the sizes of all pages
-- are roughly the same (that's not how it is in reality)
local function nearest_page(belsize, engsize, beloffs)
local bel_frac_page_start = beloffs / belsize
local bel_frac_page_end = (beloffs + 1) / belsize
local best_overlap = 0
local best_eng_offs = nil
for i = 0, engsize - 1 do
local eng_frac_page_start = i / engsize
local eng_frac_page_end = (i + 1) / engsize
local overlap = calc_overlap(eng_frac_page_start, eng_frac_page_end, bel_frac_page_start, bel_frac_page_end)
if overlap > best_overlap then
best_overlap = overlap
best_eng_offs = i
end
end
return best_eng_offs
end
-- Return either just a plain number or a link to an English book chapter
-- with the approximate page. Implemented via having some tabulated data with
-- chapters layout for a few known books.
local function format_page_num(page_name, num)
local page_name = page_name:gsub("/.*$", "")
if translated_books[page_name] then
for _, translated_book in ipairs(translated_books[page_name]) do
if #translated_book.bel_chapters == #translated_book.eng_chapters then
chapter = nil
for i = 1, #translated_book.bel_chapters do
if translated_book.bel_chapters[i] > num then
break
end
chapter = i
end
if chapter and chapter ~= #translated_book.bel_chapters then
local engsize = translated_book.eng_chapters[chapter + 1] -
translated_book.eng_chapters[chapter]
local belsize = translated_book.bel_chapters[chapter + 1] -
translated_book.bel_chapters[chapter]
local beloffs = num - translated_book.bel_chapters[chapter]
local engoffs = nearest_page(belsize, engsize, beloffs)
local result = "[[" .. translated_book.prefix .. tostring(chapter) ..
"#" .. tostring(translated_book.eng_chapters[chapter] + engoffs) .. "|" .. tostring(num) .. "]]"
if translated_book.subst then
for k, v in pairs(translated_book.subst) do
result = result:gsub(k, v)
end
end
return result
end
end
end
else
return tostring(num)
end
end
local function _page_number(cond, page_name, leftpad, rightpad)
leftpad = leftpad or ""
rightpad = rightpad or ""
if not page_name then
page_name = mw.title.getCurrentTitle().text
end
local page_name = page_name:gsub("^.*:", "")
local page = mw.ext.proofreadPage.newPage(page_name)
local num = tonumber(page.displayedNumber)
if not num then
return ""
end
if cond and (cond == 'цотны' or cond == 'цотная') then
if num % 2 == 0 then
return leftpad .. format_page_num(page_name, num) .. rightpad
end
end
if cond and (cond == 'няцотны' or cond == 'няцотная') then
if num % 2 ~= 0 then
return leftpad .. format_page_num(page_name, num) .. rightpad
end
end
if not cond or cond == '' or cond == 'любы' or cond == 'любая' or cond == 'заўсёды' then
return leftpad .. format_page_num(page_name, num) .. rightpad
end
return ""
end
function p.page_number(frame)
local cond = (frame.args['калі'] or frame.args[1]) or (frame:getParent().args['калі'] or frame:getParent().args[1])
local leftpad = (frame.args['л'] or frame.args[2]) or (frame:getParent().args['л'] or frame:getParent().args[2])
local rightpad = (frame.args['п'] or frame.args[3]) or (frame:getParent().args['п'] or frame:getParent().args[3])
local pagename = (frame.args['старонка'] or frame.args[4]) or (frame:getParent().args['старонка'] or frame:getParent().args[4])
return _page_number(cond, pagename, leftpad, rightpad)
end
-- This should be in a different module, but initially added here for testing
function p.footer_padding(frame)
local spacing = (frame.args[1]) or (frame:getParent().args[1])
if spacing then
return frame:preprocess("\n\n<references/><div style=\"height:" .. spacing .. ";font-size:" .. spacing .. ";\"> </div>")
end
return frame:preprocess("\n\n<references/>")
end
p._page_number = _page_number
return p