Modul:vote table
A modult a Modul:vote table/doc lapon tudod dokumentálni
local export = {}
-- This function returns the full vote page.
local function getFullPage(pageName)
local pageObject = mw.title.new(pageName)
return pageObject:getContent()
end
-- This function returns the start date of a vote, in the format of "Dec 9".
-- It uses the full page contents as the only parameter.
local function startDateFullPage(fullPage)
local result = ""
local startDateFull = string.match(fullPage, "Vote start.-%(UTC%)")
local startDateParts = mw.text.split(startDateFull, "Vote start.-: ")
local dateString = startDateParts[2]
local languageObject = mw.language.new("en")
local success, startDate = pcall(languageObject.formatDate, languageObject, "M j", dateString)
if success then
result = startDate
else
mw.log('Unparseable "date" in startDateFullPage function of Module:vote_table: ' .. (dateString or startDateFull))
result = startDateFull
end
return result
end
-- This function returns the portion of a vote page with the actual votes, without the vote description and the decision.
-- It uses the full page contents as theonly parameter.
local function pageExcerptFullPage(fullPage)
-- This is the offset of the match first match of "Enter '# {{support}} ~~~~' on next blank line", which appears in the first support section.
local offset = string.find(fullPage, "Enter '# {{support}} ~~~~' on next blank line", 1, 1) or 0
-- cutDescription cuts the description at the start of the vote, based on the offset parameter.
-- cutDecision cuts the decision at the end of the vote, based on the "==== Decision ====" header.
-- result is the part of the page that has the actual list of votes.
local cutDescription = string.sub(fullPage, offset, 100000000)
local cutDecision = mw.text.split(cutDescription, "==== Decision ====", true)
local result = cutDecision[1]
return result
end
-- This function returns a variable with a list of all people who voted in the page.
local function countVotesFullPage(fullPage)
local votesText = pageExcerptFullPage(fullPage)
local votes = {}
-- The line is a match, as long as it starts with a "#" but not with "##", "#*" or "#:". So, the line is a vote, not a comment to a vote.
-- matchLine (boolean) is true if the line is a match.
-- Example of accepted line: # {{support}} --[[User:Example|Example]] ([[User talk:Example|talk]]) 03:16, 26 November 2015 (UTC)
for line in mw.text.gsplit(votesText, "\n") do
local matchLine = false
if string.sub(line, 1, 1) == "#" then
matchLine = true
local tmp = string.sub(line, 1, 2);
if tmp == "##" or tmp == "#*" or tmp == "#:" then
matchLine = false
end
end
if matchLine then
local linkedUser=""
-- Checks all links (in the format: [[link]]) in the current line.
for link in string.gmatch(line, "%[%[.-%]%]") do
-- The link is a match when it points to a user page or talk page.
-- matchUserLink (boolean) is true if the link is a match.
local matchUserLink = false
if string.sub(link, 1, 7):lower() == "[[user:" then
matchUserLink = true
end
if string.sub(link, 1, 12):lower() == "[[user talk:" then
matchUserLink = true
end
-- Consider the line: # {{support}} per [[User:Example2]] --[[User:Example|Example]] ([[User talk:Example|talk]]) 01:00, 13 September 2015 (UTC)
-- It has two links (a user page and a talk page). Only the last link is ultimately used as the parameter "linkedUser".
-- Sometimes, a person has only the link to the user page or the talk page, this makes sure their votes are counted too.
if matchUserLink then
linkedUser = link
end
end
if linkedUser ~= "" then
-- linkedUser = [[User:Example#foo|Example]] (with brackets, link format, sometimes section links)
-- unlinkedUser = Example (just the user name, unlike linkedUser)
local cutNamespace = mw.text.split(linkedUser, ":", true)
local cutAfterPipe = mw.text.split(cutNamespace[2], "|", true)
local cutAfterHash = mw.text.split(cutAfterPipe[1], "#", true)
local unlinkedUser = cutAfterHash[1]
if votes[unlinkedUser] == nil then
votes[unlinkedUser] = 1
else
votes[unlinkedUser] = votes[unlinkedUser] + 1;
end
end
end
end
return votes
end
function export.createTable(frame)
-- Concerning the page "Wiktionary:Votes/Active":
-- pageObject is the page object,
-- fullPage is the full contents of the page.
local pageObject = mw.title.new("Wiktionary:Votes/Active")
local fullPage = pageObject:getContent()
-- startList is the start of the list of votes.
-- endList is the end of the list of votes.
-- For startList, we locate "{{votes/layout" in the code and add 14. The addition of 14 is because otherwise the "{{votes/layout" would be present in the final result.
-- For endList, we locate "}}" in the code and subtract 1. The subtraction of 1 is because otherwise "}" would be present in the final result.
local startList = string.find(fullPage, "{{votes/layout", 1, 1)
startList = startList + 14
local endList = string.find(fullPage, "}}", 1, 1)
endList = endList - 1
-- list is just the list of votes, as a single string.
local list = string.sub(fullPage, startList, endList)
list = mw.text.trim(list)
-- parts = the list of votes, as an array separated by the "|" in the original text.
local parts = mw.text.split(list, "|", true)
-- firstVote -> the first vote to be shown; use 1 to show the first vote (frame.args[1] = 1st template argument)
-- lastVote -> the upper limit, how many votes (vote columns) can be shown on the table at most. (frame.args[2] = 2nd template argument)
local firstVote = tonumber(frame.args[1])
local lastVote = tonumber(frame.args[2])
-- voteOrder -> key = # of vote in the order, value = vote name
-- activeVotes -> key = vote name, value = true by default, unless the vote didn't start or already ended
-- voteContents -> key = vote name, value = the contents of each vote page
-- voteStatusText -> key = vote name, value = the status text, if it exists, or "" (empty string)
-- voteStartDate -> key = vote name, value = the end date, in the format "Dec 9"
-- voteEndDate -> key = vote name, value = the end date, in the format "Dec 9"
local voteOrder = {}
local activeVotes = {}
local voteContents = {}
local voteStatusText = {}
local voteStartDate = {}
local voteEndDate = {}
local i = firstVote
while i <= lastVote and parts[i * 3] do
local vote = parts[i * 3]
table.insert(voteOrder, parts[i * 3])
activeVotes[vote] = true
voteContents[vote] = getFullPage("Wiktionary:Votes/" .. vote)
voteStatusText[vote] = parts[i * 3 + 1] or ""
voteStartDate[vote] = startDateFullPage(voteContents[vote])
voteEndDate[vote] = parts[i * 3 - 1]
i = i + 1
end
-- Parse all votes
local voteTable = {}
for _, vote in pairs(voteOrder) do
voteTable[vote] = countVotesFullPage(voteContents[vote])
end
-- people = the name of each separate people that voted in at least one vote page
-- numberOfPeople = number of people that voted in at least one vote page
local people = {}
local numberOfPeople = 0;
for _, vote in pairs(voteOrder) do
-- count = (key = user name; value = number of votes in the given vote page)
-- only the key (user name) is used below.
local count = voteTable[vote]
-- We are building the list "people", with all people that voted in at least one vote page.
-- alreadyListed = checks if the person is already listed in "people", to avoid repetition.
-- When adding a new person in "people", the "numberOfPeople" is increased by 1.
for countKey, countValue in pairs(count) do
local alreadyListed = false
for peopleKey, peopleValue in pairs(people) do
if countKey == peopleValue then
alreadyListed = true
end
end
if alreadyListed == false then
table.insert(people, countKey)
numberOfPeople = numberOfPeople + 1
end
end
end
-- Sorting "people" alphabetically.
table.sort(people)
-- Starting the table. (variable "result")
local result = "<table class='wikitable'>"
result = result .. "<tr>"
result = result .. "<th>#</th>"
local i = 0;
for k, v in pairs(voteOrder) do
result = result .. "<th style=\"white-space: nowrap\">[vote " .. firstVote + i .. "]</th>"
i = i + 1
end
result = result .. "</tr>"
result = result .. "<tr>"
result = result .. "<th>Ends</th>"
for k, v in pairs(voteOrder) do
result = result .. "<th style=\"white-space: nowrap\">" .. voteEndDate[v] .. "</th>"
end
result = result .. "</tr>"
result = result .. "<tr>"
result = result .. "<th>Title</th>"
for k, v in pairs(voteOrder) do
local voteTitleWithPrefix = v
local splitVoteTitle = mw.text.split(voteTitleWithPrefix, "/", true)
local voteTitleWithoutPrefix = splitVoteTitle[2]
result = result .. "<th>[[Wiktionary:Votes/" .. voteTitleWithPrefix .. "|" .. voteTitleWithoutPrefix .. "]]</th>"
end
result = result .. "</tr>"
for peopleKey, peopleValue in pairs(people) do
result = result .. "<tr>"
result = result .. "<th style=\"white-space: nowrap\">[[User:" .. peopleValue .. "|" .. peopleValue .. "]]</th>"
for _, v in pairs(voteOrder) do
local pageName = v
local fullPage = voteContents[v]
if peopleKey == 1 then
if mw.ustring.find(fullPage, "{{premature}}") then
result = result .. "<th style=\"text-align: center; background-color: lightgray; white-space: nowrap\" rowspan=\"" .. numberOfPeople .. "\">'''starts: " .. voteStartDate[v] .. "'''</td>"
activeVotes[v] = false
elseif mw.ustring.find(voteStatusText[v], "%a") then
result = result .. "<th style=\"text-align: center; background-color: lightgray\" rowspan=\"" .. numberOfPeople .. "\">" .. voteStatusText[v] .. "'''</td>"
activeVotes[v] = false
end
end
if activeVotes[v] == true then
local count = voteTable[v]
local personVoted = false;
for countKey, countValue in pairs(count) do
if countKey == peopleValue then
personVoted = true
end
end
if personVoted == true then
result = result .. "<td style=\"text-align:center\">✔</td>"
else
result = result .. "<td></td>"
end
end
end
result = result .. "</tr>"
end
result = result .. "</table>"
return result
end
return export