<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.agency/index.php?action=history&amp;feed=atom&amp;title=Module%3AExcerpt</id>
		<title>Module:Excerpt - Revision history</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.agency/index.php?action=history&amp;feed=atom&amp;title=Module%3AExcerpt"/>
		<link rel="alternate" type="text/html" href="https://wiki.agency/index.php?title=Module:Excerpt&amp;action=history"/>
		<updated>2026-04-29T23:32:38Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.30.1</generator>

	<entry>
		<id>https://wiki.agency/index.php?title=Module:Excerpt&amp;diff=9740&amp;oldid=prev</id>
		<title>Admin: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.agency/index.php?title=Module:Excerpt&amp;diff=9740&amp;oldid=prev"/>
				<updated>2018-11-06T09:06:46Z</updated>
		
		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr style=&quot;vertical-align: top;&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 09:06, 6 November 2018&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://wiki.agency/index.php?title=Module:Excerpt&amp;diff=9739&amp;oldid=prev</id>
		<title>Certes: Extract a section when processing a redirect to Page#Section.  (Pending change in sandbox not promoted yet.)</title>
		<link rel="alternate" type="text/html" href="https://wiki.agency/index.php?title=Module:Excerpt&amp;diff=9739&amp;oldid=prev"/>
				<updated>2018-11-05T11:24:48Z</updated>
		
		<summary type="html">&lt;p&gt;Extract a section when processing a redirect to Page#Section.  (Pending change in sandbox not promoted yet.)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
local mRedirect = require(&amp;#039;Module:Redirect&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
-- Get a redirect target (or nil if not a redirect) without using the expensive title object property .isRedirect&lt;br /&gt;
local function getRedirectTarget(titleObject)&lt;br /&gt;
	local content = titleObject:getContent()&lt;br /&gt;
	if not content then return nil end&lt;br /&gt;
	return mRedirect.getTargetFromText(content)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local errors&lt;br /&gt;
-- Return blank text, or an error message if requested&lt;br /&gt;
local function err(text)&lt;br /&gt;
	if errors then error(text, 2) end&lt;br /&gt;
	return &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- In text, match pre..list[1]..post or pre..list[2]..post or ...&lt;br /&gt;
local function matchany(text, pre, list, post)&lt;br /&gt;
	local match&lt;br /&gt;
	for i = 1, #list do&lt;br /&gt;
		match = mw.ustring.match(text, pre .. list[i] .. post)&lt;br /&gt;
		if match then return match end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get a page&amp;#039;s content, following redirects, and processing file description pages for files.&lt;br /&gt;
-- Also returns the page name, or the target page name if a redirect was followed, or false if no page found&lt;br /&gt;
local function getContent(page, frame)&lt;br /&gt;
	local title = mw.title.new(page) -- Read description page (for :File:Foo rather than File:Foo)&lt;br /&gt;
	if not title then return false, false end&lt;br /&gt;
&lt;br /&gt;
	local redir = getRedirectTarget(title)&lt;br /&gt;
	if redir then title = mw.title.new(redir) end&lt;br /&gt;
&lt;br /&gt;
	if title.namespace == 6 then&lt;br /&gt;
		frame = frame or mw.getCurrentFrame()&lt;br /&gt;
		return frame:preprocess(&amp;quot;{{&amp;quot; .. title.prefixedText .. &amp;quot;}}&amp;quot;), redir or title.prefixedText&lt;br /&gt;
	else&lt;br /&gt;
		return title:getContent(), redir or title.prefixedText&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Check image for suitability&lt;br /&gt;
local function checkimage(image)&lt;br /&gt;
	local page = matchany(image, &amp;quot;&amp;quot;, {&amp;quot;[Ff]ile&amp;quot;, &amp;quot;[Ii]mage&amp;quot;}, &amp;quot;%s*:[^|%]]*&amp;quot;) -- match File:(name) or Image:(name)&lt;br /&gt;
	if not page then return false end&lt;br /&gt;
&lt;br /&gt;
	-- Limit to image types: .gif, .jpg, .jpeg, .png, .svg, .tiff, .xcf (exclude .ogg audio etc.)&lt;br /&gt;
	if not matchany(page, &amp;quot;%.&amp;quot;, {&amp;quot;[Gg][Ii][Ff]&amp;quot;, &amp;quot;[Jj][Pp][Ee]?[Gg]&amp;quot;, &amp;quot;[Pp][Nn][Gg]&amp;quot;, &amp;quot;[Ss][Vv][Gg]&amp;quot;, &amp;quot;[Tt][Ii][Ff][Ff]&amp;quot;, &amp;quot;[Xx][Cc][Ff]&amp;quot;}, &amp;quot;%s*$&amp;quot;) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local desc = getContent(page)&lt;br /&gt;
	return ( desc and desc ~= &amp;quot;&amp;quot; and not mw.ustring.match(desc, &amp;quot;[Nn]on%-free&amp;quot;) ) and true or false -- hide non-free image&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Attempt to parse [[File:...]] or [[Image:...]], either anywhere (start=false) or at the start only (start=true)&lt;br /&gt;
local function parseimage(text, start)&lt;br /&gt;
	local startre = &amp;quot;&amp;quot;&lt;br /&gt;
	if start then startre = &amp;quot;^&amp;quot; end -- a true flag restricts search to start of string&lt;br /&gt;
	local image = matchany(text, startre .. &amp;quot;%[%[%s*&amp;quot;, {&amp;quot;[Ff]ile&amp;quot;, &amp;quot;[Ii]mage&amp;quot;}, &amp;quot;%s*:.*&amp;quot;) -- [[File: or [[Image: ...&lt;br /&gt;
	if image then&lt;br /&gt;
		image = mw.ustring.match(image, &amp;quot;%b[]%s*&amp;quot;) -- matching [[...]] to handle wikilinks nested in caption&lt;br /&gt;
	end&lt;br /&gt;
	return image&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Parse a caption, which ends at a | (end of parameter) or } (end of infobox) but may contain nested [..] and {..}&lt;br /&gt;
local function parsecaption(caption)&lt;br /&gt;
	if not caption then return nil end&lt;br /&gt;
	local len = mw.ustring.len(caption)&lt;br /&gt;
	local pos = 1&lt;br /&gt;
	while pos &amp;lt;= len do&lt;br /&gt;
		local linkstart, linkend = mw.ustring.find(caption, &amp;quot;%b[]&amp;quot;, pos)&lt;br /&gt;
		linkstart = linkstart or len + 1 -- avoid comparison with nil when no link&lt;br /&gt;
		local templatestart, templateend = mw.ustring.find(caption, &amp;quot;%b{}&amp;quot;, pos)&lt;br /&gt;
		templatestart = templatestart or len + 1 -- avoid comparison with nil when no template&lt;br /&gt;
		local argend = mw.ustring.find(caption, &amp;quot;[|}]&amp;quot;, pos) or len + 1&lt;br /&gt;
		if linkstart &amp;lt; templatestart and linkstart &amp;lt; argend then&lt;br /&gt;
			pos = linkend + 1 -- skip wikilink&lt;br /&gt;
		elseif templatestart &amp;lt; argend then&lt;br /&gt;
			pos = templateend + 1 -- skip template&lt;br /&gt;
		else -- argument ends before the next wikilink or template&lt;br /&gt;
			return mw.ustring.sub(caption, 1, argend - 1)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end					&lt;br /&gt;
&lt;br /&gt;
-- Attempt to construct a [[File:...]] block from {{infobox ... |image= ...}}&lt;br /&gt;
local function argimage(text)&lt;br /&gt;
	local token = nil&lt;br /&gt;
	local hasNamedArgs = mw.ustring.find(text, &amp;quot;|&amp;quot;) and mw.ustring.find(text, &amp;quot;=&amp;quot;)&lt;br /&gt;
	if not hasNamedArgs then return nil end -- filter out any template that obviously doesn&amp;#039;t contain an image&lt;br /&gt;
&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;&amp;lt;!%-%-imagemap%-%-&amp;gt;&amp;#039;, &amp;#039;|imagemap=&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- find all images&lt;br /&gt;
	local hasImages = false&lt;br /&gt;
	local images = {}&lt;br /&gt;
	for position, image in mw.ustring.gmatch(text, &amp;quot;|%s*[^=|]-[Ii][Mm][Aa][Gg][Ee][^=|]-%s*=%s*()(.*)&amp;quot;) do&lt;br /&gt;
		hasImages = true&lt;br /&gt;
		images[position] = image&lt;br /&gt;
	end&lt;br /&gt;
	for position, image in mw.ustring.gmatch(text, &amp;quot;|%s*[^=|]-[Pp][Hh][Oo][Tt][Oo][^=|]-%s*=%s*()(.*)&amp;quot;) do&lt;br /&gt;
		hasImages = true&lt;br /&gt;
		images[position] = image&lt;br /&gt;
	end&lt;br /&gt;
	for position, image in mw.ustring.gmatch(text, &amp;quot;|%s*[^=|{}]-%s*=%s*()%[?%[?([^|{}]*%.%a%a%a%a?)%s*%f[|}]&amp;quot;) do&lt;br /&gt;
		hasImages = true&lt;br /&gt;
		if not images[position] then&lt;br /&gt;
			images[position] = image&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not hasImages then return nil end&lt;br /&gt;
&lt;br /&gt;
	-- find all captions&lt;br /&gt;
	local captions = {}&lt;br /&gt;
	local capture_from = 0&lt;br /&gt;
	while capture_from &amp;lt; #text do&lt;br /&gt;
		local position, caption = mw.ustring.match(text, &amp;quot;|%s*[^=|]*[Cc][Aa][Pp][Tt][Ii][Oo][Nn][^=|]*%s*=%s*()([^\n]+)&amp;quot;, capture_from)&lt;br /&gt;
		if caption then&lt;br /&gt;
			-- extend caption to parse &amp;quot;| caption = Foo {{Template\n on\n multiple lines}} Bar\n&amp;quot;&lt;br /&gt;
			local bracedCaption = mw.ustring.match(text, &amp;quot;^[^\n]-%b{}[^\n]+&amp;quot;, position);&lt;br /&gt;
			if bracedCaption and bracedCaption ~= &amp;quot;&amp;quot; then caption = bracedCaption end&lt;br /&gt;
			caption = mw.text.trim(caption)&lt;br /&gt;
			local captionStart = mw.ustring.sub(caption, 1, 1)&lt;br /&gt;
			if captionStart == &amp;#039;|&amp;#039; or captionStart == &amp;#039;}&amp;#039; then caption = nil end&lt;br /&gt;
		end&lt;br /&gt;
		if caption then&lt;br /&gt;
			-- find nearest image, and use same index for captions table&lt;br /&gt;
			local i = position&lt;br /&gt;
			while i &amp;gt; 0 and not images[i] do&lt;br /&gt;
				i = i - 1&lt;br /&gt;
				if images[i] then&lt;br /&gt;
					if not captions[i] then&lt;br /&gt;
						captions[i] = parsecaption(caption)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			capture_from = position&lt;br /&gt;
		else&lt;br /&gt;
			capture_from = #text&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- find all alt text&lt;br /&gt;
	local altTexts = {}&lt;br /&gt;
	for position, altText in mw.ustring.gmatch(text, &amp;quot;|%s*[Aa][Ll][Tt]%s*=%s*()([^\n]*)&amp;quot;) do&lt;br /&gt;
		if altText then&lt;br /&gt;
			altText = mw.text.trim(altText)&lt;br /&gt;
			local altTextStart = mw.ustring.sub(altText, 1, 1)&lt;br /&gt;
			if altTextStart == &amp;#039;|&amp;#039; or altTextStart == &amp;#039;}&amp;#039; then altText = nil end&lt;br /&gt;
		end&lt;br /&gt;
		if altText then&lt;br /&gt;
			-- find nearest image, and use same index for altTexts table&lt;br /&gt;
			local i = position&lt;br /&gt;
			while i &amp;gt; 0 and not images[i] do&lt;br /&gt;
				i = i - 1&lt;br /&gt;
				if images[i] then&lt;br /&gt;
					if not altTexts[i] then&lt;br /&gt;
						altTexts[i] = altText&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- find all image sizes&lt;br /&gt;
	local imageSizes = {}&lt;br /&gt;
	for position, imageSizeMatch in mw.ustring.gmatch(text, &amp;quot;|%s*[Ii][Mm][Aa][Gg][Ee][ _]?[Ss][Ii][Zz][Ee]%s*=%s*()([^}|\n]*)&amp;quot;) do&lt;br /&gt;
		local imageSize = mw.ustring.match(imageSizeMatch, &amp;quot;=%s*([^}|\n]*)&amp;quot;)&lt;br /&gt;
		if imageSize then&lt;br /&gt;
			imageSize = mw.text.trim(imageSize )&lt;br /&gt;
			local imageSizeStart = mw.ustring.sub(imageSize, 1, 1)&lt;br /&gt;
			if imageSizeStart == &amp;#039;|&amp;#039; or imageSizeStart == &amp;#039;}&amp;#039; then imageSize = nil end&lt;br /&gt;
		end&lt;br /&gt;
		if imageSize then&lt;br /&gt;
			-- find nearest image, and use same index for imageSizes table&lt;br /&gt;
			local i = position&lt;br /&gt;
			while i &amp;gt; 0 and not images[i] do&lt;br /&gt;
				i = i - 1&lt;br /&gt;
				if images[i] then&lt;br /&gt;
					if not imageSizes[i] then&lt;br /&gt;
						imageSizes[i] = imageSize&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- sort the keys of the images table (in a table sequence), so that images can be iterated over in order&lt;br /&gt;
	local keys = {}&lt;br /&gt;
	for key, val in pairs(images) do&lt;br /&gt;
		table.insert(keys, key)&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(keys)&lt;br /&gt;
&lt;br /&gt;
	 -- add in relevant optional parameters for each image: caption, alt text and image size&lt;br /&gt;
	local imageTokens = {}&lt;br /&gt;
	for _, index in ipairs(keys) do&lt;br /&gt;
		local image = images[index]&lt;br /&gt;
		local token = parseimage(image, true) -- look for image=[[File:...]] etc.&lt;br /&gt;
		if not token then&lt;br /&gt;
			image = mw.ustring.match(image, &amp;quot;^[^}|\n]*&amp;quot;) -- remove later arguments&lt;br /&gt;
			token = &amp;quot;[[&amp;quot; -- Add File: unless name already begins File: or Image:&lt;br /&gt;
			if not matchany(image, &amp;quot;^&amp;quot;, {&amp;quot;[Ff]ile&amp;quot;, &amp;quot;[Ii]mage&amp;quot;}, &amp;quot;%s*:&amp;quot;) then&lt;br /&gt;
				token = token .. &amp;quot;File:&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
			token = token .. image&lt;br /&gt;
			local caption = captions[index]&lt;br /&gt;
			if caption and mw.ustring.match(caption, &amp;quot;%S&amp;quot;) then token = token .. &amp;quot;|&amp;quot; .. caption end&lt;br /&gt;
			local alt = altTexts[index]&lt;br /&gt;
			if alt then token = token .. &amp;quot;|alt=&amp;quot; .. alt end&lt;br /&gt;
			local image_size = imageSizes[index]&lt;br /&gt;
			if image_size and mw.ustring.match(image_size, &amp;quot;%S&amp;quot;) then token = token .. &amp;quot;|&amp;quot; .. image_size end&lt;br /&gt;
			token = token .. &amp;quot;]]&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		token = mw.ustring.gsub(token, &amp;quot;\n&amp;quot;,&amp;quot;&amp;quot;) .. &amp;quot;\n&amp;quot;&lt;br /&gt;
		table.insert(imageTokens, token)&lt;br /&gt;
	end&lt;br /&gt;
	return imageTokens&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Help gsub convert imagemaps into standard images&lt;br /&gt;
local function convertImagemap(imagemap)&lt;br /&gt;
	local image = matchany(imagemap, &amp;quot;[&amp;gt;\n]%s*&amp;quot;, {&amp;quot;[Ii]mage:&amp;quot;, &amp;quot;[Ff]ile:&amp;quot;}, &amp;quot;[^\n]*&amp;quot;)&lt;br /&gt;
	if image then&lt;br /&gt;
		return &amp;quot;&amp;lt;!--imagemap--&amp;gt;[[&amp;quot; .. mw.ustring.gsub(image, &amp;quot;[&amp;gt;\n]%s*&amp;quot;, &amp;quot;&amp;quot;, 1) .. &amp;quot;]]&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;quot;&amp;quot; -- remove entire block if image can&amp;#039;t be extracted&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Help gsub to remove unwanted templates&lt;br /&gt;
local function striptemplate(t)&lt;br /&gt;
	-- If template is unwanted then return &amp;quot;&amp;quot; (gsub will replace by nothing), else return nil (gsub will keep existing string)&lt;br /&gt;
	local unwanted = {&amp;quot;[Ee]fn&amp;quot;, &amp;quot;[Ee]fn%-[lu][arg]&amp;quot;, &amp;quot;[Ee]l[mn]&amp;quot;, &amp;quot;[Rr]p?&amp;quot;, &amp;quot;[Ss]fn[bmp]&amp;quot;, &amp;quot;[Ss]f[bn]&amp;quot;, &amp;quot;NoteTag&amp;quot;, &amp;quot;#[Tt]ag:%s*[Rr]ef&amp;quot;, &amp;quot;[Rr]efn?&amp;quot;,&lt;br /&gt;
	 &amp;quot;[CcDd]n&amp;quot;, &amp;quot;[Cc]itation needed&amp;quot;, &amp;quot;[Dd]isambiguation needed&amp;quot;, &amp;quot;[Ff]eatured article&amp;quot;, &amp;quot;[Gg]ood article&amp;quot;,&lt;br /&gt;
	 &amp;quot;[Dd]ISPLAYTITLE&amp;quot;, &amp;quot;[Ss]hort[ _]+description&amp;quot;, &amp;quot;[Cc]itation&amp;quot;, &amp;quot;[Cc]ite[%- _]+[%w_%s]-&amp;quot;, &amp;quot;[Cc]oor[%w_%s]-&amp;quot;,&lt;br /&gt;
	 &amp;quot;[Uu]?n?[Rr]eliable source[%?%w_%s]-&amp;quot;, &amp;quot;[Rr]s%??&amp;quot;, &amp;quot;[Vv]c&amp;quot;, &amp;quot;[Vv]erify credibility&amp;quot;,&lt;br /&gt;
	 -- aliases for Clarification needed&lt;br /&gt;
	 &amp;quot;[Cc]f[ny]&amp;quot;, &amp;quot;[Cc]larification[ _]+inline&amp;quot;, &amp;quot;[Cc]larification[%- _]*needed&amp;quot;, &amp;quot;[Cc]larification&amp;quot;, &amp;quot;[Cc]larify%-inline&amp;quot;, &amp;quot;[Cc]larify%-?me&amp;quot;,&lt;br /&gt;
	 &amp;quot;[Cc]larify[ _]+inline&amp;quot;, &amp;quot;[Cc]larify&amp;quot;, &amp;quot;[Cc]LARIFY&amp;quot;, &amp;quot;[Cc]onfusing%-inline&amp;quot;, &amp;quot;[Cc]onfusing%-short&amp;quot;, &amp;quot;[Ee]xplainme&amp;quot;, &amp;quot;[Hh]uh[ _]*%??&amp;quot;, &amp;quot;[Ww]hat%?&amp;quot;,&lt;br /&gt;
	 &amp;quot;[Ii]nline[ _]+[Uu]nclear&amp;quot;, &amp;quot;[Ii]n[ _]+what[ _]+sense&amp;quot;, &amp;quot;[Oo]bscure&amp;quot;, &amp;quot;[Pp]lease[ _]+clarify&amp;quot;, &amp;quot;[Uu]nclear[ _]+inline&amp;quot;, &amp;quot;[Ww]hat&amp;#039;s[ _]+this%?&amp;quot;,&lt;br /&gt;
	 &amp;quot;[Gg]eoQuelle&amp;quot;,&lt;br /&gt;
	 -- Primary source etc.&lt;br /&gt;
	 &amp;quot;[Pp]s[ci]&amp;quot;, &amp;quot;[Nn]psn&amp;quot;, &amp;quot;[Nn]on%-primary[ _]+source[ _]+needed&amp;quot;, &amp;quot;[Ss]elf%-published[%w_%s]-&amp;quot;, &amp;quot;[Uu]ser%-generated[%w_%s]-&amp;quot;,&lt;br /&gt;
	 &amp;quot;[Pp]rimary source[%w_%s]-&amp;quot;, &amp;quot;[Ss]econdary source[%w_%s]-&amp;quot;, &amp;quot;[Tt]ertiary source[%w_%s]-&amp;quot;, &amp;quot;[Tt]hird%-party[%w_%s]-&amp;quot;,&lt;br /&gt;
	 -- aliases for Disambiguation (page) and similar&lt;br /&gt;
	 &amp;quot;[Bb]egriffsklärung&amp;quot;, &amp;quot;[Dd][Aa][Bb]&amp;quot;, &amp;quot;[Dd]big&amp;quot;, &amp;quot;[%w_%s]-%f[%w][Dd]isam[%w_%s]-&amp;quot;, &amp;quot;[Hh][Nn][Dd][Ii][Ss]&amp;quot;,&lt;br /&gt;
	 -- aliases for Failed verification&lt;br /&gt;
	 &amp;quot;[Bb]adref&amp;quot;, &amp;quot;[Ff]aile?[ds] ?[rv][%w_%s]-&amp;quot;, &amp;quot;[Ff][Vv]&amp;quot;, &amp;quot;[Nn][Ii]?[Cc][Gg]&amp;quot;, &amp;quot;[Nn]ot ?in ?[crs][%w_%s]-&amp;quot;, &amp;quot;[Nn]ot specifically in source&amp;quot;,&lt;br /&gt;
	 &amp;quot;[Vv]erification[%- _]failed&amp;quot;,&lt;br /&gt;
	 -- aliases for When&lt;br /&gt;
	 &amp;quot;[Aa]s[ _]+of[ _]+when%??&amp;quot;, &amp;quot;[Aa]s[ _%-]+of%??&amp;quot;, &amp;quot;[Cc]larify date&amp;quot;, &amp;quot;[Dd]ate[ _]*needed&amp;quot;, &amp;quot;[Nn]eeds?[ _]+date&amp;quot;, &amp;quot;[Rr]ecently&amp;quot;, &amp;quot;[Ss]ince[ _]+when%??&amp;quot;,&lt;br /&gt;
	 &amp;quot;[Ww]HEN&amp;quot;, &amp;quot;[Ww]hen%??&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
	if matchany(t, &amp;quot;^{{%s*&amp;quot;, unwanted, &amp;quot;%s*%f[|}]&amp;quot;) then return &amp;quot;&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	-- If template is wanted but produces an unwanted reference then return the string with |shortref or |ref removed&lt;br /&gt;
	local noref = mw.ustring.gsub(t, &amp;quot;|%s*shortref%s*%f[|}]&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
	noref = mw.ustring.gsub(noref, &amp;quot;|%s*ref%s*%f[|}]&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	-- If a wanted template has unwanted nested templates, purge them too&lt;br /&gt;
	noref = mw.ustring.sub(noref, 1, 2) .. mw.ustring.gsub(mw.ustring.sub(noref, 3), &amp;quot;%b{}&amp;quot;, striptemplate)&lt;br /&gt;
	if noref ~= t then return noref end&lt;br /&gt;
&lt;br /&gt;
	return nil -- not an unwanted template: keep&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Convert a comma-separated list of numbers or min-max ranges into a list of booleans, e.g. &amp;quot;1,3-5&amp;quot; → {1=true,2=false,3=true,4=true,5=true}&lt;br /&gt;
local function numberflags(str)&lt;br /&gt;
	local ranges = mw.text.split(str, &amp;quot;,&amp;quot;) -- parse ranges, e.g. &amp;quot;1,3-5&amp;quot; → {&amp;quot;1&amp;quot;,&amp;quot;3-5&amp;quot;}&lt;br /&gt;
	local flags = {}&lt;br /&gt;
	for _, r in pairs(ranges) do&lt;br /&gt;
		local min, max = mw.ustring.match(r, &amp;quot;^%s*(%d+)%s*%-%s*(%d+)%s*$&amp;quot;) -- &amp;quot;3-5&amp;quot; → min=3 max=5&lt;br /&gt;
		if not max then	min, max = mw.ustring.match(r, &amp;quot;^%s*((%d+))%s*$&amp;quot;) end -- &amp;quot;1&amp;quot; → min=1 max=1&lt;br /&gt;
		if max then&lt;br /&gt;
			for p = min, max do flags[p] = true end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return flags&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- a basic parser to trim down extracted wikitext&lt;br /&gt;
--   @param text : Wikitext to be processed&lt;br /&gt;
--   @param options : A table of options...&lt;br /&gt;
--          options.paraflags : Which number paragraphs to keep, as either a string (e.g. `1,3-5`) or a table (e.g. `{1=true,2=false,3=true,4=true,5=true}`. If not present, all paragraphs will be kept.&lt;br /&gt;
--          options.fileflags : table of which files to keep, as either a string (e.g. `1,3-5`) or a table (e.g. `{1=true,2=false,3=true,4=true,5=true}`&lt;br /&gt;
--          options.fileargs : args for the [[File:]] syntax, such as `left`&lt;br /&gt;
--   @param filesOnly : If set, only return the files and not the prose&lt;br /&gt;
local function parse(text, options, filesOnly)&lt;br /&gt;
	local allparas = true -- keep all paragraphs?&lt;br /&gt;
	if options.paraflags then&lt;br /&gt;
		if type(options.paraflags) ~= &amp;quot;table&amp;quot; then options.paraflags = numberflags(options.paraflags) end&lt;br /&gt;
		for _, v in pairs(options.paraflags) do&lt;br /&gt;
			if v then allparas = false end -- if any para specifically requested, don&amp;#039;t keep all&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if filesOnly then&lt;br /&gt;
		allparas = false&lt;br /&gt;
		options.paraflags = {}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local maxfile = 0 -- for efficiency, stop checking images after this many have been found&lt;br /&gt;
	if options.fileflags then&lt;br /&gt;
		if type(options.fileflags) ~= &amp;quot;table&amp;quot; then options.fileflags = numberflags(options.fileflags) end&lt;br /&gt;
		for k, v in pairs(options.fileflags) do&lt;br /&gt;
			if v and k &amp;gt; maxfile then maxfile = k end -- set maxfile = highest key in fileflags&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local fileargs = options.fileargs and mw.text.trim(options.fileargs)&lt;br /&gt;
	if fileargs == &amp;#039;&amp;#039; then fileargs = nil end&lt;br /&gt;
&lt;br /&gt;
	local leadstart = nil -- have we found some text yet?&lt;br /&gt;
	local t = &amp;quot;&amp;quot; -- the stripped down output text&lt;br /&gt;
	local filetext = &amp;quot;&amp;quot; -- output text with concatenated [[File:Foo|...]]\n entries&lt;br /&gt;
	local files = 0 -- how many images so far&lt;br /&gt;
	local paras = 0 -- how many paragraphs so far&lt;br /&gt;
	local startLine = true -- at the start of a line (no non-spaces found since last \n)?&lt;br /&gt;
&lt;br /&gt;
	text = mw.ustring.gsub(text,&amp;quot;^%s*&amp;quot;,&amp;quot;&amp;quot;) -- remove initial white space&lt;br /&gt;
	repeat -- loop around parsing a template, image or paragraph&lt;br /&gt;
		local token = mw.ustring.match(text, &amp;quot;^%b{}%s*&amp;quot;) or false -- {{Template}}&lt;br /&gt;
		local line = mw.ustring.match(text, &amp;quot;[^\n]*&amp;quot;)&lt;br /&gt;
		if token and line and mw.ustring.len(token) &amp;lt; mw.ustring.len(line) then -- template is followed by text (but it may just be other templates)&lt;br /&gt;
			line = mw.ustring.gsub(line, &amp;quot;%b{}&amp;quot;, &amp;quot;&amp;quot;) -- remove all templates from this line&lt;br /&gt;
			-- if anything is left, other than an incomplete further template or an image, keep the template: it counts as part of the line&lt;br /&gt;
			if mw.ustring.find(line, &amp;quot;%S&amp;quot;) and not matchany(line, &amp;quot;^%s*&amp;quot;, { &amp;quot;{{&amp;quot;, &amp;quot;%[%[%s*[Ff]ile:&amp;quot;, &amp;quot;%[%[%s*[Ii]mage:&amp;quot; }, &amp;quot;&amp;quot;) then&lt;br /&gt;
				token = nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if token then -- found a template which is not the prefix to a line of text&lt;br /&gt;
			if leadstart then -- lead has already started, so keep the template within the text, unless it&amp;#039;s a whole line (navbox etc.)&lt;br /&gt;
				if not filesOnly and not startLine then t = t .. token end&lt;br /&gt;
			elseif files &amp;lt; maxfile then -- discard template, but if we are still collecting images...&lt;br /&gt;
				local images = argimage(token) or {}&lt;br /&gt;
				if not images then&lt;br /&gt;
					local image = parseimage(token, false) -- look for embedded [[File:...]], |image=, etc.&lt;br /&gt;
					if image then table.insert(images, image) end&lt;br /&gt;
				end&lt;br /&gt;
				for _, image in ipairs(images) do&lt;br /&gt;
					if files &amp;lt; maxfile and checkimage(image) then -- if image is found and qualifies (not a sound file, non-free, etc.)&lt;br /&gt;
						files = files + 1 -- count the file, whether displaying it or not&lt;br /&gt;
						if options.fileflags and options.fileflags[files] then -- if displaying this image&lt;br /&gt;
							image = mw.ustring.gsub(image, &amp;quot;|%s*frameless%s*%f[|%]]&amp;quot;, &amp;quot;&amp;quot;) -- make image a thumbnail, not frameless etc.&lt;br /&gt;
							image = mw.ustring.gsub(image, &amp;quot;|%s*framed?%s*%f[|%]]&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
							if not matchany(image, &amp;quot;|%s*&amp;quot;, {&amp;quot;thumb&amp;quot;, &amp;quot;thumbnail&amp;quot;}, &amp;quot;%s*%f[|%]]&amp;quot;) then&lt;br /&gt;
								image = mw.ustring.gsub(image, &amp;quot;(%]%]%s*)$&amp;quot;, &amp;quot;|thumb%1&amp;quot;)&lt;br /&gt;
							end&lt;br /&gt;
							if fileargs then image = mw.ustring.gsub(image, &amp;quot;(%]%]%s*)$&amp;quot;, &amp;quot;|&amp;quot; .. fileargs .. &amp;quot;%1&amp;quot;) end&lt;br /&gt;
							filetext = filetext .. image&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else -- the next token in text is not a template&lt;br /&gt;
			token = parseimage(text, true)&lt;br /&gt;
			if token then -- the next token in text looks like an image&lt;br /&gt;
				if files &amp;lt; maxfile and checkimage(token) then -- if more images are wanted and this is a wanted image&lt;br /&gt;
					files = files + 1&lt;br /&gt;
					if options.fileflags and options.fileflags[files] then&lt;br /&gt;
						local image = token -- copy token for manipulation by adding |right etc. without changing the original&lt;br /&gt;
						if fileargs then image = mw.ustring.gsub(image, &amp;quot;(%]%]%s*)$&amp;quot;, &amp;quot;|&amp;quot; .. fileargs .. &amp;quot;%1&amp;quot;) end&lt;br /&gt;
						filetext = filetext .. image&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			else -- got a paragraph, which ends at a file, image, blank line or end of text&lt;br /&gt;
				local afterend = mw.ustring.len(text) + 1&lt;br /&gt;
				local blankpos = mw.ustring.find(text, &amp;quot;\n%s*\n&amp;quot;) or afterend -- position of next paragraph delimiter (or end of text)&lt;br /&gt;
				local endpos = math.min( -- find position of whichever comes first: [[File:, [[Image: or paragraph delimiter&lt;br /&gt;
				 mw.ustring.find(text, &amp;quot;%[%[%s*[Ff]ile%s*:&amp;quot;) or afterend,&lt;br /&gt;
				 mw.ustring.find(text, &amp;quot;%[%[%s*[Ii]mage%s*:&amp;quot;) or afterend,&lt;br /&gt;
				 blankpos)&lt;br /&gt;
				token = mw.ustring.sub(text, 1, endpos-1)&lt;br /&gt;
				if blankpos &amp;lt; afterend and blankpos == endpos then -- paragraph ends with a blank line&lt;br /&gt;
					token = token .. mw.ustring.match(text, &amp;quot;\n%s*\n&amp;quot;, blankpos)&lt;br /&gt;
				end&lt;br /&gt;
				leadstart = leadstart or mw.ustring.len(t) + 1 -- we got a paragraph, so mark the start of the lead section&lt;br /&gt;
				paras = paras + 1&lt;br /&gt;
				if allparas or (options.paraflags and options.paraflags[paras]) then t = t .. token end -- add if this paragraph wanted&lt;br /&gt;
			end -- of &amp;quot;else got a paragraph&amp;quot;&lt;br /&gt;
		end -- of &amp;quot;else not a template&amp;quot;&lt;br /&gt;
&lt;br /&gt;
		if token then text = mw.ustring.sub(text, mw.ustring.len(token)+1) end -- remove parsed token from remaining text&lt;br /&gt;
		startLine = mw.ustring.find(token, &amp;quot;\n%s*$&amp;quot;); -- will the next token be the first non-space on a line?&lt;br /&gt;
	until not text or text == &amp;quot;&amp;quot; or not token or token == &amp;quot;&amp;quot; -- loop until all text parsed&lt;br /&gt;
&lt;br /&gt;
	text = mw.ustring.gsub(filetext .. t, &amp;quot;\n+$&amp;quot;, &amp;quot;&amp;quot;) -- remove trailing line feeds, so &amp;quot;{{Transclude text excerpt|Foo}} more&amp;quot; flows on one line&lt;br /&gt;
	return text, leadstart&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function cleanupText(text, leadOnly)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;&amp;lt;!%-%-.-%-%-&amp;gt;&amp;quot;,&amp;quot;&amp;quot;) -- remove HTML comments&lt;br /&gt;
	if leadOnly then&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;quot;%c%s*==.*&amp;quot;,&amp;quot;&amp;quot;) -- remove first ==Heading== and everything after it&lt;br /&gt;
	end&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;&amp;lt;noinclude&amp;gt;.-&amp;lt;/noinclude&amp;gt;&amp;quot;, &amp;quot;&amp;quot;) -- remove noinclude bits&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;&amp;lt;%s*[Rr]ef[^&amp;gt;]-/%s*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;) -- remove refs cited elsewhere&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;&amp;lt;%s*[Rr]ef.-&amp;gt;.-&amp;lt;%s*/%s*ref%s*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;) -- remove refs&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;&amp;lt;%s*[Ii]magemap.-&amp;gt;.-&amp;lt;%s*/%s*imagemap%s*&amp;gt;&amp;quot;, convertImagemap) -- convert imagemaps into standard images&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;%b{}&amp;quot;, striptemplate) -- remove unwanted templates such as references&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;%s*{{%s*[Tt][Oo][Cc].-}}&amp;quot;, &amp;quot;&amp;quot;) -- remove most common tables of contents&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;%s*__[A-Z]*TOC__&amp;quot;, &amp;quot;&amp;quot;) -- remove TOC behavior switches&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;\n%s*{{%s*[Pp]p%-.-}}&amp;quot;, &amp;quot;\n&amp;quot;) -- remove protection templates&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;%s*{{[^{|}]*[Ss]idebar%s*}}&amp;quot;, &amp;quot;&amp;quot;) -- remove most sidebars&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;%s*{{[^{|}]*%-[Ss]tub%s*}}&amp;quot;, &amp;quot;&amp;quot;) -- remove most stub templates&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;%s*%[%[%s*:?[Cc]ategory:.-%]%]&amp;quot;, &amp;quot;&amp;quot;) -- remove categories&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;^:[^\n]+\n&amp;quot;,&amp;quot;&amp;quot;) -- remove DIY hatnote indented with a colon&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Parse a ==Section== from a page&lt;br /&gt;
local function getsection(text, section, mainonly)&lt;br /&gt;
	local level, content = mw.ustring.match(text .. &amp;quot;\n&amp;quot;, &amp;quot;\n(==+)%s*&amp;quot; .. section .. &amp;quot;%s*==.-\n(.*)&amp;quot;)&lt;br /&gt;
	if not content then return nil end -- no such section&lt;br /&gt;
	local nextsection&lt;br /&gt;
	if mainonly then&lt;br /&gt;
		nextsection = &amp;quot;\n==.*&amp;quot; -- Main part of section terminates at any level of header&lt;br /&gt;
	else&lt;br /&gt;
		nextsection = &amp;quot;\n==&amp;quot; .. mw.ustring.rep(&amp;quot;=?&amp;quot;, #level - 2) .. &amp;quot;[^=].*&amp;quot; -- &amp;quot;===&amp;quot; → &amp;quot;\n===?[^=].*&amp;quot;, matching &amp;quot;==&amp;quot; or &amp;quot;===&amp;quot; but not &amp;quot;====&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	content = mw.ustring.gsub(content, nextsection, &amp;quot;&amp;quot;) -- remove later sections with headings at this level or higher&lt;br /&gt;
	return content&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Main function returns a string value: text of the lead of a page&lt;br /&gt;
local function main(pagenames, options)&lt;br /&gt;
	if not pagenames or #pagenames &amp;lt; 1 then return err(&amp;quot;No page names given&amp;quot;) end&lt;br /&gt;
	local pagename&lt;br /&gt;
	local text&lt;br /&gt;
	local pagecount = #pagenames&lt;br /&gt;
	local firstpage = pagenames[1] or &amp;quot;(nil)&amp;quot; -- save for error message, as it the name will be deleted&lt;br /&gt;
&lt;br /&gt;
	-- read the page, or a random one if multiple pages were provided&lt;br /&gt;
	if pagecount &amp;gt; 1 then math.randomseed(os.time()) end&lt;br /&gt;
	while not text and pagecount &amp;gt; 0 do&lt;br /&gt;
		local pagenum = 1&lt;br /&gt;
		if pagecount &amp;gt; 1 then pagenum = math.random(pagecount) end -- pick a random title&lt;br /&gt;
		pagename = pagenames[pagenum]&lt;br /&gt;
		if pagename and pagename ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			pagename = mw.ustring.match(pagename, &amp;quot;%[%[%s*(.-)[%]|]&amp;quot;) or pagename -- &amp;quot;[[Foo|Bar]]&amp;quot; → &amp;quot;Foo&amp;quot;&lt;br /&gt;
			pagename = mw.ustring.gsub(pagename, &amp;quot;^%s+&amp;quot;, &amp;quot;&amp;quot;) -- strip leading ...&lt;br /&gt;
			pagename = mw.ustring.gsub(pagename, &amp;quot;%s+$&amp;quot;, &amp;quot;&amp;quot;) -- ...and trailing white space&lt;br /&gt;
&lt;br /&gt;
			if pagename and pagename ~= &amp;quot;&amp;quot; then&lt;br /&gt;
				local pn, section = mw.ustring.match(pagename, &amp;quot;(.-)#(.*)&amp;quot;)&lt;br /&gt;
				pagename = pn or pagename&lt;br /&gt;
				text, normalisedPagename = getContent(pagename)&lt;br /&gt;
				if not normalisedPagename then&lt;br /&gt;
					return err(&amp;quot;No title for page name &amp;quot; .. pagename)&lt;br /&gt;
				else&lt;br /&gt;
					pagename = normalisedPagename&lt;br /&gt;
				end&lt;br /&gt;
				if text and options.nostubs then&lt;br /&gt;
					local isStub = mw.ustring.find(text, &amp;quot;%s*{{[^{|}]*%-[Ss]tub%s*}}&amp;quot;)&lt;br /&gt;
					if isStub then text = nil end&lt;br /&gt;
				end&lt;br /&gt;
				if not section then&lt;br /&gt;
					section = mw.ustring.match(pagename, &amp;quot;.-#(.*)&amp;quot;) -- parse redirect to Page#Section&lt;br /&gt;
				end&lt;br /&gt;
				if text and section then text = getsection(text, section) end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if not text then table.remove(pagenames, pagenum) end -- this one didn&amp;#039;t work; try another&lt;br /&gt;
		pagecount = pagecount - 1 -- ensure that we exit the loop after at most #pagenames iterations&lt;br /&gt;
	end&lt;br /&gt;
	if not text then return err(&amp;quot;Cannot read a valid page: first name is &amp;quot; .. firstpage) end&lt;br /&gt;
&lt;br /&gt;
	text = cleanupText(text, true)&lt;br /&gt;
	text, leadstart = parse(text, options)&lt;br /&gt;
&lt;br /&gt;
	-- replace the bold title or synonym near the start of the article by a wikilink to the article&lt;br /&gt;
	local lang = mw.language.getContentLanguage()&lt;br /&gt;
	local pos = mw.ustring.find(text, &amp;quot;&amp;#039;&amp;#039;&amp;#039;&amp;quot; .. lang:ucfirst(pagename) .. &amp;quot;&amp;#039;&amp;#039;&amp;#039;&amp;quot;, 1, true) -- look for &amp;quot;&amp;#039;&amp;#039;&amp;#039;Foo&amp;#039;&amp;#039;&amp;#039; is...&amp;quot; (uc) or &amp;quot;A &amp;#039;&amp;#039;&amp;#039;foo&amp;#039;&amp;#039;&amp;#039; is...&amp;quot; (lc)&lt;br /&gt;
	 or mw.ustring.find(text, &amp;quot;&amp;#039;&amp;#039;&amp;#039;&amp;quot; .. lang:lcfirst(pagename) .. &amp;quot;&amp;#039;&amp;#039;&amp;#039;&amp;quot;, 1, true) -- plain search: special characters in pagename represent themselves&lt;br /&gt;
	if pos then&lt;br /&gt;
		local len = mw.ustring.len(pagename)&lt;br /&gt;
		text = mw.ustring.sub(text, 1, pos + 2) .. &amp;quot;[[&amp;quot; .. mw.ustring.sub(text, pos + 3, pos + len + 2) .. &amp;quot;]]&amp;quot; .. mw.ustring.sub(text, pos + len + 3, -1) -- link it&lt;br /&gt;
	else -- look for anything unlinked in bold, assumed to be a synonym of the title (e.g. a person&amp;#039;s birth name)&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;quot;(.-&amp;#039;&amp;#039;&amp;#039;)(.-&amp;#039;*)&amp;#039;&amp;#039;&amp;#039;&amp;quot;, function(a, b)&lt;br /&gt;
			if mw.ustring.len(a) &amp;lt; 100 + (leadstart or 0) and not mw.ustring.find(b, &amp;quot;%[&amp;quot;) then ---if early in article and not wikilinked&lt;br /&gt;
				return a .. &amp;quot;[[&amp;quot; .. pagename .. &amp;quot;|&amp;quot; .. b .. &amp;quot;]]&amp;#039;&amp;#039;&amp;#039;&amp;quot; -- replace &amp;#039;&amp;#039;&amp;#039;Foo&amp;#039;&amp;#039;&amp;#039; by &amp;#039;&amp;#039;&amp;#039;[[pagename|Foo]]&lt;br /&gt;
			else&lt;br /&gt;
				return nil -- instruct gsub to make no change&lt;br /&gt;
			end&lt;br /&gt;
		 end, 1) -- &amp;quot;end&amp;quot; here terminates the anonymous replacement function(a, b) passed to gsub&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if options.more then text = text .. &amp;quot; &amp;#039;&amp;#039;&amp;#039;[[&amp;quot; .. pagename .. &amp;quot;|&amp;quot; .. options.more .. &amp;quot;]]&amp;#039;&amp;#039;&amp;#039;&amp;quot; end -- wikilink to article for more info&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Shared template invocation code for lead and random functions&lt;br /&gt;
local function invoke(frame, func)&lt;br /&gt;
	-- args = { 1,2,... = page names, paragraphs = list e.g. &amp;quot;1,3-5&amp;quot;, files = list, more = text}&lt;br /&gt;
	local args = {} -- args[k] = frame.args[k] or frame:getParent().args[k] for all k in either (numeric or not)&lt;br /&gt;
	for k, v in pairs(frame:getParent().args) do args[k] = v end&lt;br /&gt;
	for k, v in pairs(frame.args) do args[k] = v end -- args from a Lua call have priority over parent args from template&lt;br /&gt;
	errors = args[&amp;quot;errors&amp;quot;] -- set the module level boolean used in local function err&lt;br /&gt;
&lt;br /&gt;
	local articlecount = #args -- must be 1 except with selected=Foo and Foo=Somepage&lt;br /&gt;
	if articlecount &amp;lt; 1 and not (func == &amp;quot;selected&amp;quot; and args[func] and args[args[func]]) then&lt;br /&gt;
		return err(&amp;quot;No articles provided&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pagenames = {}&lt;br /&gt;
	if func == &amp;quot;lead&amp;quot; then&lt;br /&gt;
		pagenames = { args[1] }&lt;br /&gt;
	elseif func == &amp;quot;linked&amp;quot; or func == &amp;quot;listitem&amp;quot; then&lt;br /&gt;
		-- Read named page and find its wikilinks&lt;br /&gt;
		local page = args[1]&lt;br /&gt;
		local text, title = getContent(page)&lt;br /&gt;
		if not title then&lt;br /&gt;
			return err(&amp;quot;No title for page name &amp;quot; .. page)&lt;br /&gt;
		elseif not text then&lt;br /&gt;
			return err(&amp;quot;No content for page name &amp;quot; .. page)&lt;br /&gt;
		end&lt;br /&gt;
		if args[&amp;quot;section&amp;quot;] then -- check relevant section only&lt;br /&gt;
			text = getsection(text, args[&amp;quot;section&amp;quot;], args[&amp;quot;sectiononly&amp;quot;])&lt;br /&gt;
			if not text then return err(&amp;quot;No section &amp;quot; .. args[&amp;quot;section&amp;quot;] .. &amp;quot; in page &amp;quot; .. page) end&lt;br /&gt;
		end&lt;br /&gt;
		-- replace annotated links with real links&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;quot;{{%s*[Aa]nnotated[ _]link%s*|%s*(.-)%s*}}&amp;quot;, &amp;quot;[[%1]]&amp;quot;)&lt;br /&gt;
		if func == &amp;quot;linked&amp;quot; then&lt;br /&gt;
			for p in mw.ustring.gmatch(text, &amp;quot;%[%[%s*([^%]|\n]*)&amp;quot;) do table.insert(pagenames, p) end&lt;br /&gt;
		else -- listitem: first wikilink on a line beginning *, :#, etc. except in &amp;quot;See also&amp;quot; or later section&lt;br /&gt;
			text = mw.ustring.gsub(text, &amp;quot;\n== *See also.*&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
			for p in mw.ustring.gmatch(text, &amp;quot;\n:*[%*#][^\n]-%[%[%s*([^%]|\n]*)&amp;quot;) do table.insert(pagenames, p) end&lt;br /&gt;
		end&lt;br /&gt;
	elseif func == &amp;quot;random&amp;quot; then&lt;br /&gt;
		-- accept any number of page names.  If more than one, we&amp;#039;ll pick one randomly&lt;br /&gt;
		for i, p in pairs(args) do&lt;br /&gt;
			if p and type(i) == &amp;#039;number&amp;#039; then table.insert(pagenames, p) end&lt;br /&gt;
		end&lt;br /&gt;
	elseif func == &amp;quot;selected&amp;quot; then&lt;br /&gt;
		local articlekey = args[func]&lt;br /&gt;
		if tonumber(articlekey) then -- normalise article number into the range 1..#args&lt;br /&gt;
			articlekey = articlekey % articlecount&lt;br /&gt;
			if articlekey == 0 then articlekey = articlecount end&lt;br /&gt;
		end&lt;br /&gt;
		pagenames = { args[articlekey] }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local options = args -- pick up miscellaneous options: more, errors, fileargs&lt;br /&gt;
	options.paraflags = numberflags(args[&amp;quot;paragraphs&amp;quot;] or &amp;quot;&amp;quot;) -- parse paragraphs, e.g. &amp;quot;1,3-5&amp;quot; → {&amp;quot;1&amp;quot;,&amp;quot;3-5&amp;quot;}&lt;br /&gt;
	options.fileflags = numberflags(args[&amp;quot;files&amp;quot;] or &amp;quot;&amp;quot;) -- parse file numbers&lt;br /&gt;
	if options.more and options.more == &amp;quot;&amp;quot; then options.more = &amp;quot;Read more...&amp;quot; end -- more= is short for this default text&lt;br /&gt;
&lt;br /&gt;
	local text = main(pagenames, options)&lt;br /&gt;
	return frame:preprocess(text)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Entry points for template callers using #invoke:&lt;br /&gt;
function p.lead(frame) return invoke(frame, &amp;quot;lead&amp;quot;) end -- {{Transclude lead excerpt}} reads the first and only article&lt;br /&gt;
function p.linked(frame) return invoke(frame, &amp;quot;linked&amp;quot;) end -- {{Transclude linked excerpt}} reads a randomly selected article linked from the given page&lt;br /&gt;
function p.listitem(frame) return invoke(frame, &amp;quot;listitem&amp;quot;) end -- {{Transclude list item excerpt}} reads a randomly selected article listed on the given page&lt;br /&gt;
function p.random(frame) return invoke(frame, &amp;quot;random&amp;quot;) end -- {{Transclude random excerpt}} reads any article (default for invoke with one argument)&lt;br /&gt;
function p.selected(frame) return invoke(frame, &amp;quot;selected&amp;quot;) end -- {{Transclude selected excerpt}} reads the article whose key is in the selected= parameter&lt;br /&gt;
&lt;br /&gt;
-- Entry points for other Lua modules&lt;br /&gt;
function p.getContent(page, frame) return getContent(page, frame) end&lt;br /&gt;
function p.getsection(text, section) return getsection(text, section) end&lt;br /&gt;
function p.parse(text, options, filesOnly) return parse(text, options, filesOnly) end&lt;br /&gt;
function p.argimage(text) return argimage(text) end&lt;br /&gt;
function p.checkimage(image) return checkimage(image) end&lt;br /&gt;
function p.parseimage(text, start) return parseimage(text, start) end&lt;br /&gt;
function p.cleanupText(text, leadOnly) return cleanupText(text, leadOnly) end&lt;br /&gt;
function p.main(pagenames, options) return main(pagenames, options) end&lt;br /&gt;
function p.numberflags(str) return numberflags(str) end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Certes</name></author>	</entry>

	</feed>