The site was updated to MediaWiki 1.43. If anything looks broken or there are glitches, report on the talk page or Discord in #wiki-support.
Module:VolDiff
Documentation for this module may be created at Module:VolDiff/doc
local p = {}
-- Helper function to parse chapter number from the chapter link
local function getChapterNumber(chapterLink)
local fullMatch = mw.ustring.match(chapterLink, "%[%[(.-)%]%]")
if fullMatch then
local splitMatch = mw.text.split(fullMatch, "|")
return splitMatch[1]
end
return nil
end
-- Helper function to extract content under a specific section header
local function extractSection(content, header)
-- Define the pattern to find the section header
local startPattern = mw.ustring.gsub(header, "=", "%%=")
-- Find the start of the specified header
local sectionStart, sectionEnd = mw.ustring.find(content, startPattern)
-- If the section is not found, return nil
if not sectionStart then
return nil
end
-- Find the next section header (either === or ==)
local nextHeaderPattern = "\n==%s*[^=]"
local nextHeaderStart, nextHeaderEnd = mw.ustring.find(content, nextHeaderPattern, sectionEnd + 1)
-- Extract the content until the next section header or the end of the content
if nextHeaderStart then
return mw.ustring.sub(content, sectionEnd + 1, nextHeaderStart - 1)
else
return mw.ustring.sub(content, sectionEnd + 1)
end
end
-- Helper function to capture the entire template, including nested braces
local function captureTemplate(content, templateName)
local templateStart, templateEnd = mw.ustring.find(content, "{{%s*" .. templateName .. "%s*[|\n]")
if not templateStart then
return nil, nil, nil
end
local finalTemplate = { mw.ustring.sub(content, templateStart, templateEnd) }
local i = templateEnd + 1
local braceCount = 2 -- Account for the initial "{{"
while i <= mw.ustring.len(content) do
local char = mw.ustring.sub(content, i, i)
finalTemplate[#finalTemplate + 1] = char
if char == '{' then
braceCount = braceCount + 1
elseif char == '}' then
braceCount = braceCount - 1
if braceCount == 0 then
break
end
end
i = i + 1
end
return table.concat(finalTemplate), templateStart, i
end
-- Helper function to capture the entire Desc parameter
local function captureDescParameter(diff)
local descStart, descEnd = mw.ustring.find(diff, "Desc%s*=%s*")
if not descStart then
return nil
end
local finalDesc = {}
local i = descEnd + 1
local braceCount = 0
while i <= mw.ustring.len(diff) - 2 do -- Subtract 2 from length to remove the }} from Diff
local char = mw.ustring.sub(diff, i, i)
finalDesc[#finalDesc + 1] = char
if char == '{' or char == '[' then
braceCount = braceCount + 1
elseif char == '}' or char == ']' then
if braceCount > 0 then
braceCount = braceCount - 1
else
break
end
elseif char == '|' and braceCount == 0 then
break
end
i = i + 1
end
return mw.text.trim(table.concat(finalDesc))
end
-- Function to find all Diff positions
local function findDiffPositions(content)
local positions = {}
local startPos = 1
while true do
local diffStart, diffEnd = mw.ustring.find(content, "{{%s*Diff%s*[|\n]", startPos)
if not diffStart then
break
end
positions[#positions + 1] = {diffStart, diffEnd}
startPos = diffEnd + 1
end
return positions
end
-- Main function to process the VolDiffs template
function p.main(frame)
local args = frame:getParent().args
local currentTitle = mw.title.getCurrentTitle().text
local sourcePage = args[1]
local sectionType = args[2] or "magazine"
local sectionHeader = sectionType == "reprint" and "===Reprint Differences===" or "===Magazine Differences==="
local result = {}
if not sourcePage then
return "Error: No source page specified."
end
-- Fetch the content from the specified source page
local startTime = os.clock()
local content = mw.title.new(sourcePage):getContent()
if not content then
return "Error: Could not fetch content from the specified source page."
end
-- Timing log: After fetching content
local fetchTime = os.clock()
mw.log('Time after fetching content: ' .. (fetchTime - startTime))
-- Extract the section content
local volDiffsContent = extractSection(content, sectionHeader)
if not volDiffsContent then
return "Error: No section found with header " .. sectionHeader
end
-- Timing log: After extracting section content
local sectionTime = os.clock()
mw.log('Time after extracting section content: ' .. (sectionTime - fetchTime))
-- Extract VolDiffs parameters
local part = mw.ustring.match(volDiffsContent, "Part%s*=%s*([^|]+)") or ""
local title = mw.ustring.match(volDiffsContent, "Title%s*=%s*([^|]+)") or ""
local label1 = mw.ustring.match(volDiffsContent, "Label1%s*=%s*([^|]*)") or ""
local label2 = mw.ustring.match(volDiffsContent, "Label2%s*=%s*([^|]*)") or ""
-- Start the VolDiffs template
result[#result + 1] = string.format('{{VolDiffs|Part=%s|Title=%s', part, title)
if label1 ~= "" then result[#result + 1] = string.format('|Label1=%s', label1) end
if label2 ~= "" then result[#result + 1] = string.format('|Label2=%s', label2) end
result[#result + 1] = '|\n'
-- Find all Diff positions
local diffPositions = findDiffPositions(volDiffsContent)
-- Timing log: After finding Diff positions
local diffPositionsTime = os.clock()
mw.log('Time after finding Diff positions: ' .. (diffPositionsTime - sectionTime))
-- Process each Diff entry
local hasDiffs = false
for _, pos in ipairs(diffPositions) do
local diffContent, _, _ = captureTemplate(volDiffsContent:sub(pos[1]), "Diff")
if diffContent then
local diffPart = mw.ustring.match(diffContent, "Part%s*=%s*([^|]+)")
local diffChapter = mw.ustring.match(diffContent, "Chapter%s*=%s*(%[%[.-%]%])")
local diffPage = mw.ustring.match(diffContent, "Page%s*=%s*([^|]+)")
local diffImage1 = mw.ustring.match(diffContent, "Image1%s*=%s*([^|]+)")
local diffImage2 = mw.ustring.match(diffContent, "Image2%s*=%s*([^|]+)")
local diffDesc = captureDescParameter(diffContent)
local diffLabel1 = mw.ustring.match(diffContent, "Label1%s*=%s*([^|]*)") or ""
local diffLabel2 = mw.ustring.match(diffContent, "Label2%s*=%s*([^|]*)") or ""
if diffPart and diffChapter and diffPage and diffImage1 and diffImage2 and diffDesc then
local chapterNumber = getChapterNumber(diffChapter)
-- Check if the current page title matches the chapter number
if chapterNumber and mw.ustring.match(currentTitle, chapterNumber) then
hasDiffs = true
result[#result + 1] = string.format('{{Diff|Part=%s|Chapter=%s|Page=%s|Image1=%s|Image2=%s|Desc=%s',
diffPart, diffChapter, diffPage, diffImage1, diffImage2, mw.text.trim(diffDesc))
-- Add optional labels if they are present
if diffLabel1 ~= "" then result[#result + 1] = string.format('|Label1=%s', diffLabel1) end
if diffLabel2 ~= "" then result[#result + 1] = string.format('|Label2=%s', diffLabel2) end
result[#result + 1] = '}}\n'
end
end
end
end
-- Timing log: After processing Diff entries
local processDiffsTime = os.clock()
mw.log('Time after processing Diff entries: ' .. (processDiffsTime - diffPositionsTime))
-- Concatenate all diff entries at once
if hasDiffs then
result[#result + 1] = '}}'
else
return "No differences found for this chapter."
end
-- Total time taken
local totalTime = processDiffsTime - fetchTime
mw.log('Total time taken: ' .. totalTime)
return frame:preprocess(table.concat(result))
end
return p