Module:Printable version
This module is rated as ready for general use. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
Usage[edit]
Search and display one book pages from its TOC page, in order to create a printable version page, and a navigation bar (automatic "previous" / "next" page buttons).
- See b:Template:printable as a printable page generator.
- b:Template:Nav (or b:Template:footer) as a navigation bar creator.
debug = false
OnlySubpages = true
local p = {}
Error = require('Module:TNT').format('I18n/Module:Printable version', 'error_invalid_toc')
Beginning1 = require('Module:TNT').format('I18n/Module:Printable version', 'header_notice')
Beginning2 = require('Module:TNT').format('I18n/Module:Printable version', 'header_cover')
Break = require('Module:TNT').format('I18n/Module:Printable version', 'page_break')
Ending1 = require('Module:TNT').format('I18n/Module:Printable version', 'footer_license')
Ending2 = require('Module:TNT').format('I18n/Module:Printable version', 'footer2')
templateLeft = require('Module:TNT').format('I18n/Module:Printable version', 'template_left')
templateRight = require('Module:TNT').format('I18n/Module:Printable version', 'template_right')
TOC = require('Module:TNT').format('I18n/Module:Printable version', 'TOC')
sep = require('Module:TNT').format('I18n/Module:Printable version', 'subpage_separator')
function p._escapePattern(pattern)
return mw.ustring.gsub(pattern, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1");
end
function p.displays_book(frame)
if not debug then Error = '' end
if frame == nil then return '' end
if frame.args == nil then return '' end
if frame.args[1] == nil then return '' end
local BookName = frame.args[1]
if (BookName ~= nil and mw.text.trim(BookName) ~= '') then
title = mw.title.new(BookName)
if frame.args[2] ~= nil and frame.args[2] ~= '' then
BookName = frame.args[2]
else
if mw.ustring.find(BookName, sep .. TOC, 1, true) ~= nil then BookName = mw.ustring.gsub(BookName, "^(.*)" .. sep .. TOC .. "$", "%1") end
end
if frame.args[3] ~= nil then OnlySubpages = false end
else
return Error
end
if (title == nil or title == '') then return Error end
text = title.getContent(title)
if (text == nil or text == '') then return Error end
-- Book subpages titles normalization to absolute names
local lines_ = mw.text.split(text, "\n")
local fullPageName
local PrintVersion = {}
for i,v in ipairs(lines_) do
if mw.text.trim(v) ~= '' then
fullPageName = p.getFullPageName(BookName, v)
if fullPageName ~= nil then
ChapterTitle = mw.title.new(fullPageName)
if (ChapterTitle ~= nil and ChapterTitle.exists) then
PageName = p.getSubpageName(BookName, fullPageName)
if (PageName ~= nil and PageName ~= '') then
if Break ~= "" then table.insert(PrintVersion, frame:expandTemplate{title = Break}) end
table.insert(PrintVersion, '\n<div style="clear:both;"></div>\n=' .. PageName .. '=\n')
end
table.insert(PrintVersion, frame:expandTemplate{ title = ':' .. fullPageName } .. '\n\n')
else
if debug then table.insert(PrintVersion, '<font color=red>Missing subpage "' .. fullPageName .. '" on line "' .. v .. '" for the book:</font> ' .. BookName .. '\n\n') end
end
end
end
end
Templates1 = ""
if Beginning1 ~= "" then Templates1 = Templates1 .. frame:expandTemplate{title = Beginning1} .. '\n' end
if Beginning2 ~= "" then Templates1 = Templates1 .. frame:expandTemplate{title = Beginning2} .. '\n' end
Templates2 = ""
if Ending1 ~= "" then Templates2 = Templates2 .. frame:expandTemplate{title = Ending1} .. '\n' end
if Ending2 ~= "" then Templates2 = Templates2 .. frame:expandTemplate{title = Ending2} .. '\n' end
return Templates1 .. table.concat(PrintVersion, "\r\n") .. Templates2
end
function p.extract_fullPageName(frame)
if frame == nil then return '' end
if frame.args == nil then return '' end
if frame.args[1] == nil then return '' end
if frame.args[2] == nil then return '' end
return p.getFullPageName(frame.args[1], frame.args[2])
end
function p.getFullPageName(BookName, chapter)
if (BookName ~= nil and mw.text.trim(BookName) ~= '') or (chapter ~= nil and mw.text.trim(chapter) ~= '') then
BookName = mw.text.trim(BookName)
chapter = mw.text.trim(chapter)
BookName = mw.ustring.gsub(BookName, "_", " ")
chapter = mw.ustring.gsub(chapter, "_", " ")
else
if debug then chapter = '<font color=red>Incorrect book or chapter name</font>' else chapter = '' end
end
chapter = mw.ustring.gsub(chapter, "{{BOOKNAME}}", BookName)
chapter = mw.ustring.gsub(chapter, "{{[Mm]odulo%|([^}]+)}}", "[[%1]]")
chapter = mw.ustring.gsub(chapter, " *%| *[0-9]*.*{{[Cc]%|([^}]+)%|[0-9]}}", "[[" .. BookName .. sep .. "%1]]")
chapter = mw.ustring.gsub(chapter, " *%| *[0-9]*.*{{[Cc]%|([^}]+)}}", "[[" .. BookName .. sep .. "%1]]")
chapter = mw.ustring.gsub(chapter, " *%[%[Image:[^%]]+%]%]", "")
chapter = mw.ustring.gsub(chapter, "{{[^}]*}}", "")
chapter = mw.ustring.gsub(chapter, "^[%#%*:; ]*", "")
chapter = mw.ustring.gsub(chapter, "%[%[%.%.?/", "[[" .. BookName .. sep)
chapter = mw.ustring.gsub(chapter, "%[%[/", "[[" .. BookName .. sep)
chapter = mw.ustring.gsub(chapter, "%/%]%]", "]]")
chapter = mw.ustring.gsub(chapter, "%/$", "")
if mw.ustring.find(chapter, "%[%[") ~= nil then
-- Pages titles extraction from the TOC
if mw.ustring.find(chapter, "%|") == nil or (mw.ustring.find(chapter, "%]") ~= nil and mw.ustring.find(chapter, "%|") > mw.ustring.find(chapter, "%]")) then
Ending = "%]"
else
if mw.ustring.find(chapter, "%/%|") == nil or mw.ustring.find(chapter, "%/%|") > mw.ustring.find(chapter, "%|") then
Ending = "%|"
else
Ending = "%/%|"
end
end
chapter = mw.text.split(chapter, Ending)[1] -- extraction of the line beginning
--chapter = mw.text.split(chapter, "%[%[")[2]
chapter = mw.ustring.gsub(chapter, "[^%[]*%[%[(.*)", "%1") -- brackets and pipes removal
if chapter == BookName or chapter == BookName .. sep or mw.ustring.find(chapter, "%#") ~= nil then
if debug then chapter = '<font color=red>Chapter = ' .. chapter .. ' => book name or another subpage name</font> with Ending = ' .. Ending else chapter = '' end
else
if OnlySubpages then
-- Book subpages only (and ignoring the other links like "see also")
if mw.ustring.find(chapter, BookName .. sep, 1, true) == nil then
if debug then chapter = "<font color=red>No book subpage into the internal link:</font> '" .. chapter .. "' doesn't include '" .. BookName .. sep .. "'" else chapter = '' end
end
end
end
else
if debug then chapter = "<font color=red>No internal link</font> for: " .. chapter .. "\n" else chapter = '' end
end
return chapter
end
function p.getSubpageName(bookName, fullPageName)
k, v = mw.ustring.gsub(fullPageName, p._escapePattern(bookName) .. '/', '')
return k
end
function p.extract_subpageName(frame)
if frame == nil then return '' end
if frame.args == nil then return '' end
if frame.args[1] == nil then return '' end
if frame.args[2] == nil then return '' end
return p.getSubpageName(frame.args[1], frame.args[2])
end
function p.displays_footer(frame)
if not debug then Error = '' end
if frame == nil then return "" end
if frame.args == nil then return "" end
if frame.args[1] == nil then return "" end
local footer = {}
local BookName = frame.args[1]
if (BookName ~= nil and mw.text.trim(BookName) ~= "") then
title = mw.title.new(BookName)
if mw.ustring.find(BookName, sep .. TOC, 1, true) ~= nil then BookName = mw.ustring.gsub(BookName, "^(.*)" .. sep .. TOC .. "$", "%1") end
else
return Error
end
local currentPageName
if frame.args[2] ~= nil and frame.args[2] ~= '' then
currentPageName = frame.args[2]
else
currentPageName = p.getSubpageName(BookName, mw.title.getCurrentTitle().fullText)
end
if (currentPageName ~= nil and mw.text.trim(currentPageName) ~= "") then
currentPageName = mw.text.trim(currentPageName)
else
return Error
end
if debug then table.insert(footer, " currentPageName = " .. currentPageName .. "\n") end
if (title == nil or title == "") then return Error end
text = title.getContent(title)
if (text == nil or text == "") then return Error end
if frame.args[3] ~= nil and frame.args[3] ~= '' then
if frame.args[3] == 'programming' then
if debug then table.insert(footer, " skin=programming\n\n") end
templateLeft = '{| style="width:100%; border:solid 1px #71c837; background:#c6e9af; color:#2d5016;" class="noprint"\n| style="text-align:left; width:33%; font-size:90%;" |[[Image:Navigation_Left_Arrow.svg|18px|link=printf|alt=]] [[printf]]\n'
templateRight = '| style="text-align:center; width:34%;" | [['..mw.title.getCurrentTitle().rootText..']]<br><b>'..mw.title.getCurrentTitle().subpageText..'</b>\n| style="text-align:right; width:33%; font-size:90%;" | [[printf]] [[Image:Navigation_Right_Arrow.svg|18px|link=printf|alt=]]\n|}'
end
end
-- Book subpages titles normalization to absolute names
local lines_ = mw.text.split(text, "\n")
local previousChapter = ""
local found = false
local fullPageName
local homepage = false
local subpageName
local rawFullPageName
if (currentPageName == BookName) then
if debug then table.insert(footer, " homepage\n") end
homepage = true
end
for i, v in ipairs(lines_) do
rawFullPageName = mw.text.trim(v)
if rawFullPageName ~= '' then
fullPageName = p.getFullPageName(BookName, rawFullPageName)
if debug then
if mw.ustring.find(fullPageName, "<font color=red>No internal link</font>") ~= nil then
fullPageName = nil
else
table.insert(footer, " research into: " .. rawFullPageName .. "\n")
table.insert(footer, " extraction of: " .. fullPageName .. "\n")
end
end
if fullPageName ~= nil then
if mw.ustring.find(fullPageName, BookName .. sep, 1, true) == nil then
if debug then table.insert(footer, " replacement of " .. fullPageName .. " by " .. BookName .. sep .. fullPageName .. "\n") end
fullPageName = BookName .. sep .. fullPageName
end
ChapterTitle = mw.title.new(fullPageName)
if (ChapterTitle ~= nil and ChapterTitle.exists) then
subpageName = p.getSubpageName(BookName, fullPageName)
if debug then table.insert(footer, " cut subpage: " .. subpageName .. "\n") end
if (subpageName ~= nil and subpageName ~= "") then
if found == true or homepage == true then
if debug then table.insert(footer, "<font color=red>Previous & next chapter insertion</font>\n") end
if homepage == false then
if previousChapter == "" then
theTemplateLeft, nb = mw.ustring.gsub(templateLeft, "printf", BookName .. "|" .. TOC)
else
theTemplateLeft, nb = mw.ustring.gsub(templateLeft, "printf", BookName .. sep .. previousChapter .. "|" .. previousChapter)
end
table.insert(footer, theTemplateLeft)
end
theTemplateRight, nb = mw.ustring.gsub(templateRight, "printf", BookName .. sep .. subpageName .. "|" .. subpageName)
table.insert(footer, theTemplateRight)
break
elseif subpageName == currentPageName then
if debug then table.insert(footer, "<font color=red>Page</font> '" .. currentPageName .. "' found\n\n") end
found = true
elseif fullPageName ~= "" then
if debug then table.insert(footer, " " .. subpageName .. " is different from " .. currentPageName .. "\n") end
previousChapter = subpageName
else
if debug then table.insert(footer, "<font color=red>The current page</font> '" .. subpageName .. "' is not '" .. currentPageName .. "'") end
end
end
else
if debug then table.insert(footer, "<font color=red>The page</font> '" .. fullPageName .. "' doesn't exist, for '" .. currentPageName .. "'\n\n") end
end
end
end
end
if found == true and table.getn(footer) == 0 then
if debug then table.insert(footer, "<font color=red>No next chapter</font>\n") end
theTemplateLeft, nb = mw.ustring.gsub(templateLeft, "printf", BookName .. sep .. previousChapter .. "|" .. previousChapter)
table.insert(footer, theTemplateLeft)
theTemplateRight, nb = mw.ustring.gsub(templateRight, "printf", BookName .. "|" .. TOC)
table.insert(footer, theTemplateRight)
end
return table.concat(footer, "")
end
return p