Module:GU Page
Jump to navigation
Jump to search
Module documentation
This documentation is transcluded from Module:GU Page/doc. [edit] [history] [purge]
Module:GU Page's function main is invoked by Template:GU Page.
Module:GU Page requires Module:DPLlua.
| Function list |
|---|
| L 6 — p.main L 13 — p.get_args_subjects L 26 — p.headfoot L 53 — p._main L 102 — p.list_pages L 143 — p.bracket_match L 173 — p.get_gu_section L 216 — p.check_article_for_subjects L 231 — p.extract_subject_gu_from_article L 253 — p.get_subject_header_start_position L 267 — p.get_all_subjects L 282 — p.get_subject |
Makes Graphical updates pages.
-- <nowiki>
local p = {}
local dpl = require('Module:DPLlua')
local MAX_PER_PAGE = 300 -- About 3 seconds time usage
function p.main(frame)
local args = frame:getParent().args
local page_no = tonumber(args.page) or 1
local subjects, subjectcats = p.get_args_subjects(args)
return p._main(args, page_no, subjects, subjectcats)
end
function p.get_args_subjects(args)
local subjects, cats = {}, {}
for i = 1, 20 do --arbitrary limit of 20 subjects
if args['subject'..i] ~= nil then
local subj = args['subject'..i]
table.insert(subjects, subj)
subj = string.gsub( string.lower( subj or ""), "s$", "")
table.insert(cats, "Graphical updates with subject " .. subj)
end
end
return subjects, cats
end
function p.headfoot(cats, subjectcats)
local title = mw.title.getCurrentTitle().text
local big_list = p.list_pages(cats, subjectcats, 5000, 0)
local total_results = #big_list
local shorter_title = title:match("(.+)/") -- grab everything up to but not including last /
if shorter_title == nil then
shorter_title = ''
end
if total_results<=MAX_PER_PAGE then
return ""
end
local total_full_pages = math.floor((total_results - 1) / MAX_PER_PAGE)
local starts,ends = {},{}
for i = 1,total_full_pages do
table.insert(starts,big_list[(i-1)*MAX_PER_PAGE+1])
table.insert(ends,big_list[i*MAX_PER_PAGE])
end
table.insert(starts,big_list[total_full_pages*MAX_PER_PAGE+1])
table.insert(ends,big_list[total_results])
local res = {}
for i = 1,total_full_pages+1 do
table.insert(res,"[[" .. shorter_title .. "/" .. tostring(i) .. "|" .. starts[i] .. " to " .. ends[i] .. "]]")
end
return table.concat(res,"\n\n")
end
function p._main(cats, page_no, subjects, subjectcats)
local headfoot_text = p.headfoot(cats, subjectcats)
local off = MAX_PER_PAGE*(page_no-1)
local pages = p.list_pages(cats, subjectcats, MAX_PER_PAGE, off)
if pages[1] then
table.sort(pages)
-- Header and footer if there are multiple GU pages for these categories
local head_text,foot_text = "",""
if headfoot_text ~= "" then
local catstr = "The following pages cover graphical updates of"
for _,v in ipairs(cats) do
if v ~= '' and string.sub(v, 1, 1) ~= '!' then
catstr = catstr .. " " .. v
end
end
catstr = catstr .. "\n\n"
head_text = catstr .. headfoot_text
foot_text = "==See also==\nThere are more graphical updates avaliable,\n\n" .. headfoot_text
end
local gu_all = {}
local section = 'DEFAULT'
if head_text ~="" then
table.insert(gu_all,head_text)
end
table.insert(gu_all,"__NOEDITSECTION__\n{{Alphabetical header}}")
for _,page in pairs(pages) do
local pagegu = p.get_gu_section(page,subjects) --getting page first
if (pagegu ~= '' and pagegu ~= nil) then
if string.sub(page,1,1)~=section then
section = string.sub(page,1,1)
table.insert(gu_all,"=="..section.."==")
end
table.insert(gu_all,pagegu)
end
end
if foot_text ~="" then
table.insert(gu_all,foot_text)
end
local gu_string = table.concat(gu_all,"\n")
local ret = mw.getCurrentFrame():preprocess(gu_string)
return ret
else
return "No graphical updates found"
end
end
function p.list_pages(cats, subjectcats, quantity, offset)
local andcats = { 'Pages with graphical updates' } -- Page must have all of these categories
local notcats = { 'Graphical updates' } -- GU gallery pages should be excluded
local orcats = {} -- Page must have at least one of these categories
for _,v in ipairs(cats) do
if v ~= '' then
if string.sub(v, 1, 1) == '!' then
table.insert(notcats, string.sub(v, 2))
else
table.insert(andcats, v)
end
end
end
for _, v in ipairs(subjectcats) do
if v ~= '' then
table.insert(orcats, v)
end
end
if #orcats > 0 then
table.insert(andcats, table.concat(orcats, '|'))
end
local dpltable = {
namespace = '',
category = andcats,
ordermethod = "title",
count = quantity,
offset = offset
}
if #notcats > 0 then
dpltable['notcategory'] = notcats
end
local page_list = dpl.ask(dpltable)
page_list['DPL time']=nil
page_list['Parse time']=nil
return page_list
end
function p.bracket_match(text,init)
local lefts = text:gmatch("(){") -- locations of left brackets
local rights = text:gmatch("()}")
local brackets = {}
for x in lefts do
brackets[x]=1
end
for x in rights do
brackets [x]=-1
end
--order by keys for easy iteration
local ordered_brackets = {}
for k in pairs(brackets) do
table.insert(ordered_brackets, k)
end
table.sort(ordered_brackets)
--Look for same number of { as }
local open_left=0
for i = 1, #ordered_brackets do
open_left = open_left + brackets[ ordered_brackets[i] ]
if open_left==0 and ordered_brackets[i]>init then
return ordered_brackets[i]
end
end
return #text --handle init too big and syntax errors
end
function p.get_gu_section(title_text,subjects)
local article = mw.title.new(title_text):getContent()
local _ , a = article:find("==Graphical updates==")
if a then
article = article:sub(a+1) -- remove everything before GU section
local last_gu=0
local gu_pos = article:gmatch("(){{GU|")
for x in gu_pos do
if x>last_gu then
last_gu = x
end
end
local last_bracket = p.bracket_match(article,last_gu)
article = article:sub(0,last_bracket)
article = article:gsub("===","====")
else -- skip if no graphical updates section found
article = ""
end
if #subjects > 0 then
local subjectsgus = p.check_article_for_subjects(article,subjects)
if subjectsgus == '' then
return ''
else
article = subjectsgus
end
end
--close unclosed comments
local left_comment = article:gmatch("()<!--") -- locations of left comments
local right_comment = article:gmatch("()-->")
local left_count, right_count = 0, 0
for _ in left_comment do
left_count = left_count+1
end
for _ in right_comment do
right_count = right_count+1
end
local close_comments = string.rep( "--> ", left_count-right_count )
return "===[[" .. title_text .. "]]===" .. article .. close_comments
end
function p.check_article_for_subjects(article,filtersubjects)
local articlesubjects = p.get_all_subjects(article)
local subjectsgus = ''
for _, avalue in pairs(articlesubjects) do --looping through subjects of the article
for _, fvalue in pairs(filtersubjects) do --looping through subjects that were requested
if avalue == fvalue then --found a match
subjectsgus = subjectsgus .. p.extract_subject_gu_from_article(article,fvalue,#filtersubjects)
end
end
end
return subjectsgus
end
function p.extract_subject_gu_from_article(article,subject,filtersubjectsamount)
local pos = p.get_subject_header_start_position(article,subject)
local gu = article:sub(pos)
local throwaway
pos, throwaway = string.find(gu,"{")
pos, throwaway = string.find(gu,"====",pos)
gu = gu:sub(1,pos) --extract the specific subject GU
pos, throwaway = string.find(gu,"}[^}]*$")
gu = gu:sub(1,pos) --remove everything after the final closing curly bracket
if (filtersubjectsamount == 1) then --remove header if only one subject
throwaway, pos = string.find(gu,"====")
if pos ~= nil then
pos = pos + 1
gu = gu:sub(pos)
throwaway, pos = string.find(gu,"====\n")
pos = pos + 1
gu = gu:sub(pos)
end
end
return '\n'..gu
end
function p.get_subject_header_start_position(article,subject)
local pos, _ = string.find(article,'{{GU|subject='..subject)
local prevgu = article:sub(1, pos)
local headerpos, _ = string.find(prevgu,"====[^====]*$")
if (headerpos ~= nil) then
headerpos = headerpos - 1
prevgu = prevgu:sub(1, headerpos)
headerpos, _ = string.find(prevgu,"====[^====]*$")
else
headerpos = pos
end
return headerpos
end
function p.get_all_subjects(article)
local subjects = {}
local position = 1
while true do --looking for all subjects
local subject, position_candidate
subject, position_candidate = p.get_subject(article,position)
if position_candidate then position = position_candidate end
if (subject == nil) then --no (more) subjects found
break
end
table.insert(subjects, subject)
end
return subjects
end
function p.get_subject(article,position)
local _ , pos = string.find(article,'|subject=',position)
if pos == nil then --no subject found
return nil,nil
end
pos = pos + 1
local subject = article:sub(pos) -- remove everything before the subject
local endpos = string.find(subject, "\n")
endpos = endpos - 1
subject = string.sub(subject,1,endpos) -- remove everything after the subject
local nextpos = pos + endpos
return subject,nextpos
end
return p