Jump to content

Module:Excerpt slideshow

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Evad37 (talk | contribs) at 10:24, 13 September 2018 (replace annotated links with real links before looking for links or list items). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local p = {}
local excerptModule =  require('Module:Excerpt')
local slideshowModule = require('Module:Random slideshow')
local randomModule = require('Module:Random')

function cleanupArgs(argsTable)
	local cleanArgs = {}
	for key, val in pairs(argsTable) do
		if type(val) == 'string' then
			val = val:match('^%s*(.-)%s*$')
			if val ~= '' then
				cleanArgs[key] = val
			end
		else
			cleanArgs[key] = val
		end
	end
	return cleanArgs
end

-- help gsub strip tables and templates that aren't part of the prose, and remove linebreaks from within other templates
local processBraces = function(t)
	local isTable = mw.ustring.sub(mw.text.trim(t), 2, 2) == '|'
	if isTable then
		return ''
	end
	-- else it's a template
	local first = mw.ustring.sub(t, 1, 1)
	local last = mw.ustring.sub(t, -1)
	local isNotPartOfProse = first == '\n' and last == '\n'
	if isNotPartOfProse then
		return ''
	end
	-- else remove internal linebreaks
	return mw.ustring.gsub(t, '\n*', '')
end

local makeGalleryArgs = function(titles, options, limit)
	options.nostubs = true
	local galleryArgs = {}
	local titlesSequence = {}
	local i = 1
	while titles[i] do
		titlesSequence[i] = titles[i]
		i  = i + 1
	end
	local randomTitles = randomModule.main('array', {t=titlesSequence, limit=limit})
	for _, title in pairs(randomTitles) do
		local excerpt = mw.text.trim(excerptModule.main({title}, options))
		if excerpt and excerpt ~= '' and #excerpt > 10 then
			-- temporarily take off the '''[[Page title|Read more...]]''' link if present
			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
			if readmore_start_index then
				excerpt = mw.ustring.sub(excerpt, 1, readmore_start_index-2)
			end
			-- strip galleries
			excerpt = mw.ustring.gsub(excerpt, "<%s*[Gg]allery.->.-<%s*/%s*[Gg]allery%s*>", "")
			-- strip tables and block templates
			excerpt = mw.ustring.gsub(excerpt..'\n', '\n?%b{}\n?', processBraces)
			excerpt = mw.text.trim(excerpt)
			-- 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
	return galleryArgs
end

local makeOptions = function(args)
	local options = args -- pick up miscellaneous options: more, errors, fileargs
	options.paraflags = excerptModule.numberflags(args.paragraphs or "") -- parse paragraphs, e.g. "1,3-5" → {"1","3-5"}
	options.fileflags = excerptModule.numberflags(args.files or "") -- parse file numbers
	return options
end

local isArticle = function(pagetitle)
	local titleObject = mw.title.new(pagetitle)
	return ( titleObject and titleObject.namespace == 0 ) and true or false
end

local getLinkedTitles = function(args, method, limit)
	local pagenames = {}
	local ii = 1
	local isNotCategory
	while args[ii] and ii < limit do
		local pageContent = excerptModule.getContent(args[ii])
		if pageContent then
			local pageSection = args["section"..ii] or args["section"]
			local sectionOnly = args["sectiononly"..ii] or args["sectiononly"]
			local text = pageContent
			if pageSection then -- check relevant section only
				text = excerptModule.getsection(pageContent, pageSection, sectionOnly) or pageContent
			end
			-- replace annotated links with real links
			text = mw.ustring.gsub(text, "{{%s*[Aa]nnotated[ _]link%s*|%s*(.-)%s*}}", "[[%1]]")
			if method == "linked" then
				for p in mw.ustring.gmatch(text, "%[%[%s*([^%]|\n]*)") do
					if isArticle(p) then
						table.insert(pagenames, p)
					end
				end
			else
				-- listitem: first wikilink on a line beginning *, :#, etc. except in "See also" or later section
				text = mw.ustring.gsub(text, "\n== *See also.*", "")
				for p in mw.ustring.gmatch(text, "\n:*[%*#][^\n]-%[%[%s*([^%]|\n]*)") do
					if isArticle(p) then
						table.insert(pagenames, p)
					end
				end
			end	
		end
		ii = ii + 1
	end
	return pagenames
end

-- Template entry points:

-- randomExcerpt: Titles specified in template parameters (equivalent to {{Transclude random excerpt}})
p.randomExcerpt = function(frame)
	local parent = frame.getParent(frame)
	local output = p._excerpt(parent.args, 'random')
	return frame:preprocess(output)
end

-- linkedExcerpt: Titles from links on one or more pages (similar to {{Transclude linked excerpt}})
p.linkedExcerpt = function(frame)
	local parent = frame.getParent(frame)
	local output = p._excerpt(parent.args, 'linked')
	return frame:preprocess(output)
end

-- listItemExcerpt: Titles from linked list items one one or more pages (similar to {{Transclude list item excerpt}})
p.listItemExcerpt = function(frame)
	local parent = frame.getParent(frame)
	local output = p._excerpt(parent.args, 'listitem')
	return frame:preprocess(output)
end


-- Module entry point:

p._excerpt = function(_args, method)
	local args = cleanupArgs(_args)
	-- 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 50
	local titles
	if method == 'linked' or method == 'listitem' then
		titles = getLinkedTitles(args, method, 50)
	else
		titles = args
	end
	local galleryArgs = makeGalleryArgs(titles, options, limit)
	return slideshowModule._main(galleryArgs, false, 'excerptSlideshow-container')
end

return p