Module:Excerpt slideshow/sandbox: Difference between revisions

Content deleted Content added
try replacing wikitext lists with html lists
shuffle around
 
(48 intermediate revisions by 7 users not shown)
Line 1:
local p = {}
local excerptModule = require('Module:Excerpt/portals/sandbox')
local slideshowModule = require('Module:Random slideshow/sandbox')
local randomModule = require('Module:Random')
 
local DEFAULT_LIMIT = 25 -- max number of excerpts to be shown in the slideshow
local SOURCE_PAGES_LIMIT = 10 -- max number of pages to check for links / list items
 
-- begin BHG addition for tracking source pages
local sourcepgagesused = {};
local sourcepgagesusedcounter = 0;
local articlelistcount = -1;
local usesEmbeddedList = false;
-- end BHG addition for tracking source pages
 
function cleanupArgs(argsTable)
Line 19 ⟶ 29:
end
 
function isDeclined(val)
local wikitextToHtmlList = function(wikitext)
if not val then return false end
local declinedWords = " decline declined exclude excluded false none not no n off omit omitted remove removed "
return string.find(declinedWords , ' '..val..' ', 1, true ) and true or false
end
 
--[[
@param {String} wikitext: Wikitext of just the list (i.e. each line is a list item)
@param {String} symbol: Special character used in the wikitext markup for the list, e.g. '*' or '#'
@param {String} outerTag: Text portion of the tag for each list or sublist, e.g. 'ul' or 'ol'
@param {String} innerTag: Text portion of the tag for each list item, e.g. 'li'
]]
local wikitextToHtmlList = function(wikitext, symbol, outerTag, innerTag)
local listParts = {}
for level, item in mw.ustring.gmatch('\n'..wikitext..'\n', '\n(%*'..symbol..'+)(.-)%f[\n]') do
table.insert(listParts, {level=level, item=item})
end
Line 28 ⟶ 50:
local htmlList = {}
for i, this in ipairs( listParts ) do
local lastLevelisFirstItem = ( i == 1 ) and '' or list[i-1]['level']
local nextLevelisLastItem = ( i == #list listParts) and '' or list[i+1]['level']
local lastLevel = isFirstItem and '' or listParts[i-1]['level']
local tags
if #lastLevel == #this.level then
tags = '</li'..innerTag..'><li'..innerTag..'>'
elseif #this.level > #lastLevel then
tags = string.rep('<ul'..outerTag..'><li'..innerTag..'>', #this.level - #lastLevel)
elseif isLastItem then
else -- #this.level < #lastLevel
tags = string.rep('</li'..innerTag..'></ul'..outerTag..'>', #lastLevel - #this.level )
else -- ( #this.level < #lastLevel ) and not last item
tags = string.rep('</'..innerTag..'></'..outerTag..'>', #lastLevel - #this.level ) .. '</'..innerTag..'><'..innerTag..'>'
end
table.insert(htmlList, tags .. this.item)
Line 43 ⟶ 68:
end
 
--[[
local replacePipesWithMagicword = function(t)
@param {String} wikitext: Wikitext excertp containg zero or more lists
return mw.ustring.gsub(t, '|', '{{!}}')
@param {String} symbol: Special character used in the wikitext markup for the list, e.g. '*' or '#'
@param {String} outerTag: Text portion of the tag for each list or sublist, e.g. 'ul' or 'ol'
@param {String} innerTag: Text portion of the tag for each list item, e.g. 'li'
]]
local gsubWikitextLists = function(wikitext, symbol, outerTag, innerTag)
-- temporarily remove list linebreaks...
wikitext = mw.ustring.gsub(wikitext..'\n', '\n%'..symbol, '¿¿¿'..symbol)
-- ...so we can grab the whole list (and just the list)...
return mw.ustring.gsub(
wikitext,
'¿¿¿%'..symbol..'[^\n]+',
function(listWikitext)
-- ...and then reinstate linebreaks...
listWikitext = mw.ustring.gsub(listWikitext, '¿¿¿%'..symbol, '\n'..symbol)
-- ...and finally do the conversion
return wikitextToHtmlList(listWikitext, symbol, outerTag, innerTag)
end
)
end
 
--[[ help gsub strip tables and templates that aren't part of the prose,
and remove linebreaks from within other templates,
and preprocess parser functions ]]
local processBraces = function(t)
local isTable = mw.ustring.sub(mw.text.trim(t), 2, 2) == '|'
Line 53 ⟶ 98:
return ''
end
-- else it's a template or parser function
local first = mw.ustring.sub(t, 1, 1)
local last = mw.ustring.sub(t, -1)
Line 60 ⟶ 105:
return ''
end
local isParserFunction = mw.ustring.sub(mw.text.trim(t), 3, 3) == '#'
-- else replace pipes and remove internal linebreaks
if isParserFunction then
return replacePipesWithMagicword(mw.ustring.gsub(t, '\n*', ''))
local frame = mw.getCurrentFrame()
return frame:preprocess(t)
end
-- else remove internal linebreaks
return mw.ustring.gsub(t, '\n*', '')
end
 
local cleanUpExcerpt = function(excerpt)
-- strip galleries
excerpt = mw.ustring.gsub(excerpt, "<%s*[Gg]allery.->.-<%s*/%s*[Gg]allery%s*>", "")
-- strip tables and block templates; strip newlines
excerpt = mw.ustring.gsub(excerpt..'\n', '\n?%b{}\n?', processBraces)
-- replace wikitext bulleted lists with html bulleted lists
excerpt = gsubWikitextLists(excerpt, '*', 'ul', 'li')
-- replace wikitext numbered lists with html numbered lists
excerpt = gsubWikitextLists(excerpt, '#', 'ol', 'li')
excerpt = mw.text.trim(excerpt)
return excerpt
end
 
localfunction makeGalleryArgs = function(titles, options, limit, nonRandom)
options.nostubs = true
local galleryArgs = {}
local titlesSequence = {}
Line 73 ⟶ 135:
i = i + 1
end
local randomTitlessortedTitles = nonRandom and titlesSequence or randomModule.main('array', {t=titlesSequence, limit=limit})
for __i, title in pairsipairs(randomTitlessortedTitles) do
if (#galleryArgs / 2) < limit then
local excerpt = mw.text.trim(excerptModule.main({title}, options))
if local excerpt andsuccess, excerpt ~= '' and #excerpt >pcall(excerptModule.get, 10title, thenoptions)
if not success then
-- temporarily take off the '''[[Page title|Read more...]]''' link if present
mw.log("require('Module:Excerpt').get failed: " .. excerpt) -- probably got a redlink
readmore_start_index, readmore_end_index, readmore_text = mw.ustring.find(excerpt, "('''%b[]''')$", -350) --- Starting from end should improve efficiency. 350 characters allows for long page titles and/or a long custom label for the link
excerpt = nil
if readmore_start_index then
excerpt = mw.ustring.sub(excerpt, 1, readmore_start_index-2)
end
if excerpt and excerpt ~= '' and #excerpt > 10 then -- check again in case we had a few characters plus (Full article...)
-- strip galleries
excerpt = mw.ustring.gsubcleanUpExcerpt(excerpt, "<%s*[Gg]allery.->.-<%s*/%s*[Gg]allery%s*>", "")
if options.more then
-- strip tables and block templates; strip newlines and replace pipes within inline templates
excerpt = mw.ustring.gsub(excerpt .. " ('\n','[[" .. title .. "|" .. options.more .. "]]''\n?%b{}\n?', processBraces)"
-- replace pipes within links
excerpt = mw.ustring.gsub(excerpt, '%b[]', replacePipesWithMagicword)
-- replace other pipes with html entity
excerpt = mw.ustring.gsub(excerpt, '|', '&#124;')
-- replace wikitext lists with html lists
excerpt = mw.ustring.gsub(excerpt..'\n', '\n%*', '¿¿¿*') -- temporarily remove linebreaks...
excerpt = mw.ustring.gsub(
excerpt, '¿¿¿%*[^\n]+', -- ...so we can grab the whole list (and just the list)...
function(listWikitext)
listWikitext = mw.ustring.gsub(listWikitext, '¿¿¿%*', '\n*') -- ...and then reinstate linebreaks
return wikitextToHtmlList(listWikitext)
end
local text = '<div style="text-align:left;">' .. mw.ustring.gsub(excerpt, '%c', '<br>') .. '</div>'
)
table.insert(galleryArgs, 'File:Blank.png')
excerpt = mw.text.trim(excerpt)
table.insert(galleryArgs, text)
-- add back the "Read more..." link if it was present
if readmore_text then
excerpt = excerpt .. " " .. readmore_text
end
local text = '<div style{{=}}text-align:left;>' .. mw.ustring.gsub(excerpt, '%c', '<br>') .. '</div>'
table.insert(galleryArgs, 'File:Blank.png')
table.insert(galleryArgs, text)
end
end
if nonRandom then
return galleryArgs
galleryArgs.random = 'false'
end
if #galleryArgs == 0 and options.nostubs then
-- try again, this time including stubs
options.nostubs = false
return makeGalleryArgs(titles, options, limit, nonRandom)
else
return galleryArgs
end
end
 
local makeOptions = function(args)
local options = args -- pick up miscellaneous options: more, errors, fileargs
options.paraflags = excerptModule.numberflagsnumberFlags(args.paragraphs or "") -- parse paragraphs, e.g. "1,3-5" → {"1","3-5"}
options.fileflags = excerptModule.numberflagsnumberFlags(args.files or "") -- parse file numbers
options.ignoreOnlyincludes = options.ignoreOnlyincludes == nil and true or options.ignoreOnlyincludes -- default to true
if args.nostubs and isDeclined(args.nostubs) then
options.nostubs = false
else
options.nostubs = true
end
return options
end
Line 135 ⟶ 195:
local text = pageContent
if pageSection then -- check relevant section only
textlocal success, result = pcall(excerptModule.getsection(getSection, pageContent, pageSection, sectionOnly) or pageContent
if not success then
mw.log("require('Module:Excerpt').getSection failed on the content of " .. args[ii] .. ": " .. result)
result = nil
end
text = result or pageContent
end
-- begin BHG addition for tracking source pages
local thisPage = mw.title.getCurrentTitle().nsText .. ":" .. mw.title.getCurrentTitle().text
thisPage = thisPage:gsub('_', ' ') -- fix the nsText part, until [[phab:T369784]] is resolved
local thisBareParam = mw.ustring.gsub(args[ii], "^([^#]+).*$", "%1", 1) -- strip any section anchor from the parameter's page name
thisBareParam = thisBareParam:gsub('_', ' ') -- support underscores in parameter's page name
if (thisPage == thisBareParam) then
usesEmbeddedList = true;
end
-- end BHG addition for tracking source pages
-- replace annotated links with real links
text = mw.ustring.gsub(text, "{{%s*[Aa]nnotated[ _]link%s*|%s*(.-)%s*}}", "[[%1]]")
Line 153 ⟶ 227:
end
end
end
-- begin BHG addition for tracking source pages
if ((method == "listitem") or (method == "linked")) then
table.insert(sourcepgagesused, args[ii])
sourcepgagesusedcounter = sourcepgagesusedcounter + 1
end
-- end BHG addition for tracking source pages
end
ii = ii + 1
end
-- begin BHG addition for tracking
articlelistcount = #pagenames
-- end BHG addition for tracking
return pagenames
end
Line 166 ⟶ 249:
local parent = frame.getParent(frame)
local output = p._excerpt(parent.args, 'random')
return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/sandbox/styles.css'} }
return frame:preprocess(output)
.. frame:preprocess(output)
end
 
Line 173 ⟶ 257:
local parent = frame.getParent(frame)
local output = p._excerpt(parent.args, 'linked')
return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/sandbox/styles.css'} }
return frame:preprocess(output)
.. frame:preprocess(output)
end
 
Line 180 ⟶ 265:
local parent = frame.getParent(frame)
local output = p._excerpt(parent.args, 'listitem')
return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/sandbox/styles.css'} }
return frame:preprocess(output)
.. frame:preprocess(output)
end
 
Line 188 ⟶ 274:
p._excerpt = function(_args, method)
local args = cleanupArgs(_args)
args.more = excerptModule.getMoreLinkText(_args.more)
-- check for blank value in more parameter
if _args.more and not args.more then
args.more = "Read more..." -- default text for blank more=
end
local galleryArgs = {}
local options = makeOptions(args)
local limit = args.limit and tonumber(args.limit) or 50DEFAULT_LIMIT
local titles
if method == 'linked' or method == 'listitem' then
titles = getLinkedTitles(args, method, 50SOURCE_PAGES_LIMIT)
else
titles = args
end
local galleryArgs = makeGalleryArgs(titles, options, limit, isDeclined(_args.random))
return slideshowModule._main(galleryArgs, false, 'excerptSlideshow-container') .. checksourcepages()
end
 
p._cleanUpExcerpt = cleanUpExcerpt
 
-- begin BHG addition for tracking source pages
function checksourcepages()
-- no tracking unless we are in Portal namespace
if (mw.title.getCurrentTitle().nsText ~= "Portal") then
return ""
end
local pagecounter = 0;
local templatecount = 0;
local outlinecount = 0;
local retval ="";
local usesEponymousArticle = false;
local debugging = false;
local thisPageBareName = mw.title.getCurrentTitle().text;
if debugging then
retval = '<div style="display:block; border:10px solid green; background-color:#efe; padding:1em; margin:1em">\n----\n'
retval = retval .. "sourcepgagesusedcounter: " .. sourcepgagesusedcounter .. "\n----\n"
retval = retval .. "pages used:"
end
local apage
for apage in arrayvalues(sourcepgagesused) do
if debugging then
retval = retval .. "\n# [[:" .. apage .. "]]"
retval = retval .. " — " .. "First 999 = /" .. string.sub(apage, 1, 999) .. "/"
end
if (string.find(apage, "^[tT]emplate ?:") == 1) then
templatecount = templatecount + 1;
end
if (string.find(apage, "^[oO]utline +of ") == 1) then
outlinecount = outlinecount + 1;
end
if (apage == thisPageBareName) then
usesEponymousArticle = true;
end
pagecounter = pagecounter + 1
end
if debugging then
retval = retval .. "\nTotal pages: " .. pagecounter
retval = retval .. "\ntemplatecount: " .. templatecount
retval = retval .. "</div>"
end
-- first do a sanity check that both counting methods have produced the same result
if (sourcepgagesusedcounter == pagecounter) then
-- if all pages are templates, then populate tracking categories
if (pagecounter == templatecount) then
if (templatecount == 1) then
retval = retval .. "[[Category:Automated article-slideshow portals with article list built solely from one template]]"
elseif (templatecount == 2) then
retval = retval .. "[[Category:Automated article-slideshow portals with article list built solely from two templates]]"
elseif (templatecount == 3) then
retval = retval .. "[[Category:Automated article-slideshow portals with article list built solely from three templates]]"
elseif (templatecount > 3) then
retval = retval .. "[[Category:Automated article-slideshow portals with article list built solely from four or more templates]]"
end
elseif (templatecount > 0) then
retval = retval .. "[[Category:Automated article-slideshow portals with article list built using one or more templates, and other sources]]"
end
end
if (outlinecount >= 1) then
retval = retval .. "[[Category:Automated article-slideshow portals with article list built using one or more outline pages]]"
end
if (articlelistcount < 2) then
retval = retval .. "[[Category:Automated article-slideshow portals with less than 2 articles in article list]]"
elseif (articlelistcount <= 5) then
retval = retval .. "[[Category:Automated article-slideshow portals with 2–5 articles in article list]]"
elseif (articlelistcount <= 10) then
retval = retval .. "[[Category:Automated article-slideshow portals with 6–10 articles in article list]]"
elseif (articlelistcount <= 15) then
retval = retval .. "[[Category:Automated article-slideshow portals with 11–15 articles in article list]]"
elseif (articlelistcount <= 20) then
retval = retval .. "[[Category:Automated article-slideshow portals with 16–20 articles in article list]]"
elseif (articlelistcount <= 25) then
retval = retval .. "[[Category:Automated article-slideshow portals with 21–25 articles in article list]]"
elseif (articlelistcount <= 30) then
retval = retval .. "[[Category:Automated article-slideshow portals with 26–30 articles in article list]]"
elseif (articlelistcount <= 40) then
retval = retval .. "[[Category:Automated article-slideshow portals with 31–40 articles in article list]]"
elseif (articlelistcount <= 50) then
retval = retval .. "[[Category:Automated article-slideshow portals with 41–50 articles in article list]]"
elseif (articlelistcount <= 100) then
retval = retval .. "[[Category:Automated article-slideshow portals with 51–100 articles in article list]]"
elseif (articlelistcount <= 200) then
retval = retval .. "[[Category:Automated article-slideshow portals with 101–200 articles in article list]]"
elseif (articlelistcount <= 500) then
retval = retval .. "[[Category:Automated article-slideshow portals with 201–500 articles in article list]]"
elseif (articlelistcount <= 1000) then
retval = retval .. "[[Category:Automated article-slideshow portals with 501–1000 articles in article list]]"
elseif (articlelistcount > 1000) then
retval = retval .. "[[Category:Automated article-slideshow portals with over 1000 articles in article list]]"
end
if usesEmbeddedList then
retval = retval .. "[[Category:Automated article-slideshow portals with embedded list]]"
end
if usesEponymousArticle then
retval = retval .. "[[Category:Automated article-slideshow portals with article list built using eponymous article]]"
end
return retval
end
 
function arrayvalues(t)
local i = 0
return function() i = i + 1; return t[i] end
end
 
-- end BHG addition for tracking source pages
return p