<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.tribesdepot.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ATranscluder</id>
	<title>Module:Transcluder - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.tribesdepot.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ATranscluder"/>
	<link rel="alternate" type="text/html" href="https://wiki.tribesdepot.com/index.php?title=Module:Transcluder&amp;action=history"/>
	<updated>2026-04-04T03:51:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://wiki.tribesdepot.com/index.php?title=Module:Transcluder&amp;diff=7752&amp;oldid=prev</id>
		<title>Bigwig: Created page with &quot;local p = {}  -- Helper function to test for truthy and falsy values local function truthy(value) 	if not value or value == &#039;&#039; or value == 0 or value == &#039;0&#039; or value == &#039;false&#039; or value == &#039;no&#039; then 		return false 	end 	return true end  -- Helper function to match from a list regular expressions -- Like so: match pre..list[1]..post or pre..list[2]..post or ... local function matchAny(text, pre, list, post, init) 	local match = {} 	for i = 1, #list do 		match = { mw.ustri...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.tribesdepot.com/index.php?title=Module:Transcluder&amp;diff=7752&amp;oldid=prev"/>
		<updated>2023-12-18T22:55:38Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local p = {}  -- Helper function to test for truthy and falsy values local function truthy(value) 	if not value or value == &amp;#039;&amp;#039; or value == 0 or value == &amp;#039;0&amp;#039; or value == &amp;#039;false&amp;#039; or value == &amp;#039;no&amp;#039; then 		return false 	end 	return true end  -- Helper function to match from a list regular expressions -- Like so: match pre..list[1]..post or pre..list[2]..post or ... local function matchAny(text, pre, list, post, init) 	local match = {} 	for i = 1, #list do 		match = { mw.ustri...&amp;quot;&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;
&lt;br /&gt;
-- Helper function to test for truthy and falsy values&lt;br /&gt;
local function truthy(value)&lt;br /&gt;
	if not value or value == &amp;#039;&amp;#039; or value == 0 or value == &amp;#039;0&amp;#039; or value == &amp;#039;false&amp;#039; or value == &amp;#039;no&amp;#039; then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Helper function to match from a list regular expressions&lt;br /&gt;
-- Like so: match pre..list[1]..post or pre..list[2]..post or ...&lt;br /&gt;
local function matchAny(text, pre, list, post, init)&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, init) }&lt;br /&gt;
		if match[1] then return unpack(match) end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function escapeString(str)&lt;br /&gt;
	return mw.ustring.gsub(str, &amp;#039;[%^%$%(%)%.%[%]%*%+%-%?%%]&amp;#039;, &amp;#039;%%%0&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Helper function to remove a string from a text&lt;br /&gt;
local function removeString(text, str)&lt;br /&gt;
	local pattern = escapeString(str)&lt;br /&gt;
	if #pattern &amp;gt; 9999 then -- strings longer than 10000 bytes can&amp;#039;t be put into regexes&lt;br /&gt;
		pattern = escapeString(mw.ustring.sub(str, 1, 999)) .. &amp;#039;.-&amp;#039; .. escapeString(mw.ustring.sub(str, -999))&lt;br /&gt;
	end&lt;br /&gt;
	return mw.ustring.gsub(text, pattern, &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Helper function to convert a comma-separated list of numbers or min-max ranges into a list of booleans&lt;br /&gt;
-- @param flags Comma-separated list of numbers or min-max ranges, for example &amp;#039;1,3-5&amp;#039;&lt;br /&gt;
-- @return Map from integers to booleans, for example {1=true,2=false,3=true,4=true,5=true}&lt;br /&gt;
-- @return Boolean indicating wether the flags should be treated as a blacklist or not&lt;br /&gt;
local function parseFlags(value)&lt;br /&gt;
	local flags = {}&lt;br /&gt;
	local blacklist = false&lt;br /&gt;
&lt;br /&gt;
	if not value then return nil, false end&lt;br /&gt;
&lt;br /&gt;
	if type(value) == &amp;#039;number&amp;#039; then&lt;br /&gt;
		if value &amp;lt; 0 then&lt;br /&gt;
			value = value * -1&lt;br /&gt;
			blacklist = true&lt;br /&gt;
		end&lt;br /&gt;
		flags = { [value] = true }&lt;br /&gt;
&lt;br /&gt;
	elseif type(value) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		if mw.ustring.sub(value, 1, 1) == &amp;#039;-&amp;#039; then&lt;br /&gt;
			blacklist = true&lt;br /&gt;
			value = mw.ustring.sub(value, 2)&lt;br /&gt;
		end&lt;br /&gt;
		local ranges = mw.text.split(value, &amp;#039;,&amp;#039;) -- split ranges: &amp;#039;1,3-5&amp;#039; to {&amp;#039;1&amp;#039;,&amp;#039;3-5&amp;#039;}&lt;br /&gt;
		for _, range in pairs(ranges) do&lt;br /&gt;
			range = mw.text.trim(range)&lt;br /&gt;
			local min, max = mw.ustring.match(range, &amp;#039;^(%d+)%s*%-%s*(%d+)$&amp;#039;) -- &amp;#039;3-5&amp;#039; to min=3 max=5&lt;br /&gt;
			if not max then	min, max = mw.ustring.match(range, &amp;#039;^((%d+))$&amp;#039;) end -- &amp;#039;1&amp;#039; to 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;
			else&lt;br /&gt;
				flags[range] = true -- if we reach this point, the string had the form &amp;#039;a,b,c&amp;#039; rather than &amp;#039;1,2,3&amp;#039;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	-- List has the form { [1] = false, [2] = true, [&amp;#039;c&amp;#039;] = false }&lt;br /&gt;
	-- Convert it to { [1] = true, [2] = true, [&amp;#039;c&amp;#039;] = true }&lt;br /&gt;
	-- But if ANY value is set to false, treat the list as a blacklist&lt;br /&gt;
	elseif type(value) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		for i, v in pairs(value) do&lt;br /&gt;
			if v == false then blacklist = true end&lt;br /&gt;
			flags[i] = true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return flags, blacklist&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Helper function to see if a value matches any of the given flags&lt;br /&gt;
local function matchFlag(value, flags)&lt;br /&gt;
	if not value then return false end&lt;br /&gt;
	value = tostring(value)&lt;br /&gt;
	local lang = mw.language.getContentLanguage()&lt;br /&gt;
	for flag in pairs(flags) do&lt;br /&gt;
		if value == tostring(flag)&lt;br /&gt;
		or lang:lcfirst(value) == flag&lt;br /&gt;
		or lang:ucfirst(value) == flag&lt;br /&gt;
		or ( not tonumber(flag) and mw.ustring.match(value, flag) ) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Helper function to convert template arguments into an array of options fit for get()&lt;br /&gt;
local function parseArgs(frame)&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for key, value in pairs(frame:getParent().args) do args[key] = value end&lt;br /&gt;
	for key, value in pairs(frame.args) do args[key] = value end -- args from Lua calls have priority over parent args from template&lt;br /&gt;
	return args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Error handling function&lt;br /&gt;
-- Throws a Lua error or returns an empty string if error reporting is disabled&lt;br /&gt;
local function throwError(key, value)&lt;br /&gt;
	local TNT = require(&amp;#039;Module:TNT&amp;#039;)&lt;br /&gt;
	local ok, message = pcall(TNT.format, &amp;#039;I18n/Module:Transcluder.tab&amp;#039;, &amp;#039;error-&amp;#039; .. key, value)&lt;br /&gt;
	if not ok then message = key end&lt;br /&gt;
	error(message, 2)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Error handling function&lt;br /&gt;
-- Returns a wiki friendly error or an empty string if error reporting is disabled&lt;br /&gt;
local function getError(key, value)&lt;br /&gt;
	local TNT = require(&amp;#039;Module:TNT&amp;#039;)&lt;br /&gt;
	local ok, message = pcall(TNT.format, &amp;#039;I18n/Module:Transcluder.tab&amp;#039;, &amp;#039;error-&amp;#039; .. key, value)&lt;br /&gt;
	if not ok then message = key end&lt;br /&gt;
	message = mw.html.create(&amp;#039;div&amp;#039;):addClass(&amp;#039;error&amp;#039;):wikitext(message)&lt;br /&gt;
	return message&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Helper function to get the local name of a namespace and all its aliases&lt;br /&gt;
-- @param name Canonical name of the namespace, for example &amp;#039;File&amp;#039;&lt;br /&gt;
-- @return Local name of the namespace and all aliases, for example {&amp;#039;File&amp;#039;,&amp;#039;Image&amp;#039;,&amp;#039;Archivo&amp;#039;,&amp;#039;Imagen&amp;#039;}&lt;br /&gt;
local function getNamespaces(name)&lt;br /&gt;
	local namespaces = mw.site.namespaces[name].aliases&lt;br /&gt;
	table.insert(namespaces, mw.site.namespaces[name].name)&lt;br /&gt;
	table.insert(namespaces, mw.site.namespaces[name].canonicalName)&lt;br /&gt;
	return namespaces&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the page wikitext, following redirects&lt;br /&gt;
-- Also returns the page name, or the target page name if a redirect was followed, or false if no page was found&lt;br /&gt;
-- For file pages, returns the content of the file description page&lt;br /&gt;
local function getText(page, noFollow)&lt;br /&gt;
	local title = mw.title.new(page)&lt;br /&gt;
	if not title then return false, false end&lt;br /&gt;
&lt;br /&gt;
	local target = title.redirectTarget&lt;br /&gt;
	if target and not noFollow then title = target end&lt;br /&gt;
&lt;br /&gt;
	local text = title:getContent()&lt;br /&gt;
	if not text then return false, title.prefixedText end&lt;br /&gt;
&lt;br /&gt;
	-- Remove &amp;lt;noinclude&amp;gt; tags&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;&amp;lt;[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]&amp;gt;.-&amp;lt;/[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]&amp;gt;&amp;#039;, &amp;#039;&amp;#039;) -- remove noinclude bits&lt;br /&gt;
&lt;br /&gt;
	-- Keep &amp;lt;onlyinclude&amp;gt; tags&lt;br /&gt;
	if mw.ustring.find(text, &amp;#039;[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]&amp;#039;) then -- avoid expensive search if possible&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;#039;&amp;lt;/[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]&amp;gt;.-&amp;lt;[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]&amp;gt;&amp;#039;, &amp;#039;&amp;#039;) -- remove text between onlyinclude sections&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;#039;^.-&amp;lt;[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]&amp;gt;&amp;#039;, &amp;#039;&amp;#039;) -- remove text before first onlyinclude section&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;#039;&amp;lt;/[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]&amp;gt;.*&amp;#039;, &amp;#039;&amp;#039;) -- remove text after last onlyinclude section&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return text, title.prefixedText&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested files out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of files to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all files.&lt;br /&gt;
-- @return Sequence of strings containing the wikitext of the requested files.&lt;br /&gt;
-- @return Original wikitext minus requested files.&lt;br /&gt;
local function getFiles(text, flags)&lt;br /&gt;
	local files = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
	local fileNamespaces = getNamespaces(&amp;#039;File&amp;#039;)&lt;br /&gt;
	local name&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for file in mw.ustring.gmatch(text, &amp;#039;%b[]&amp;#039;) do&lt;br /&gt;
		if matchAny(file, &amp;#039;%[%[%s*&amp;#039;, fileNamespaces, &amp;#039;%s*:.*%]%]&amp;#039;) then&lt;br /&gt;
			name = mw.ustring.match(file, &amp;#039;%[%[[^:]-:([^]|]+)&amp;#039;)&lt;br /&gt;
			count = count + 1&lt;br /&gt;
			if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )&lt;br /&gt;
			or blacklist and flags and not flags[count] and not matchFlag(name, flags) then&lt;br /&gt;
				table.insert(files, file)&lt;br /&gt;
			else&lt;br /&gt;
				text = removeString(text, file)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return files, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested tables out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of tables to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all tables.&lt;br /&gt;
-- @return Sequence of strings containing the wikitext of the requested tables.&lt;br /&gt;
-- @return Original wikitext minus requested tables.&lt;br /&gt;
local function getTables(text, flags)&lt;br /&gt;
	local tables = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
	local id&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for t in mw.ustring.gmatch(&amp;#039;\n&amp;#039; .. text, &amp;#039;\n%b{}&amp;#039;) do&lt;br /&gt;
		if mw.ustring.sub(t, 1, 3) == &amp;#039;\n{|&amp;#039; then&lt;br /&gt;
			id = mw.ustring.match(t, &amp;#039;\n{|[^\n]-id%s*=%s*[&amp;quot;\&amp;#039;]?([^&amp;quot;\&amp;#039;\n]+)[&amp;quot;\&amp;#039;]?[^\n]*\n&amp;#039;)&lt;br /&gt;
			count = count + 1&lt;br /&gt;
			if not blacklist and ( not flags or flags[count] or flags[id] )&lt;br /&gt;
			or blacklist and flags and not flags[count] and not flags[id] then&lt;br /&gt;
				table.insert(tables, t)&lt;br /&gt;
			else&lt;br /&gt;
				text = removeString(text, t)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return tables, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested templates out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of templates to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all templates.&lt;br /&gt;
-- @return Sequence of strings containing the wikitext of the requested templates.&lt;br /&gt;
-- @return Original wikitext minus requested templates.&lt;br /&gt;
local function getTemplates(text, flags)&lt;br /&gt;
	local templates = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
	local name&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for template in mw.ustring.gmatch(text, &amp;#039;{%b{}}&amp;#039;) do&lt;br /&gt;
		if mw.ustring.sub(template, 1, 3) ~= &amp;#039;{{#&amp;#039; then -- skip parser functions like #if&lt;br /&gt;
			name = mw.text.trim( mw.ustring.match(template, &amp;#039;{{([^}|\n]+)&amp;#039;) ) -- get the template name&lt;br /&gt;
			count = count + 1&lt;br /&gt;
			if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )&lt;br /&gt;
			or blacklist and flags and not flags[count] and not matchFlag(name, flags) then&lt;br /&gt;
				table.insert(templates, template)&lt;br /&gt;
			else&lt;br /&gt;
				text = removeString(text, template)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return templates, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested template parameters out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of parameters to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all parameters.&lt;br /&gt;
-- @return Map from parameter name to value, NOT IN THE ORIGINAL ORDER&lt;br /&gt;
-- @return Original wikitext minus requested parameters.&lt;br /&gt;
local function getParameters(text, flags)&lt;br /&gt;
	local parameters = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
	local params, count, parts, key, value&lt;br /&gt;
	for template in mw.ustring.gmatch(text, &amp;#039;{%b{}}&amp;#039;) do&lt;br /&gt;
		params = mw.ustring.match(template, &amp;#039;{{[^|}]-|(.+)}}&amp;#039;)&lt;br /&gt;
		if params then&lt;br /&gt;
			count = 0&lt;br /&gt;
			-- Temporarily replace pipes in subtemplates, tables and links to avoid chaos&lt;br /&gt;
			for subtemplate in mw.ustring.gmatch(params, &amp;#039;%b{}&amp;#039;) do&lt;br /&gt;
				params = mw.ustring.gsub(params, escapeString(subtemplate), mw.ustring.gsub(mw.ustring.gsub(subtemplate, &amp;#039;%%&amp;#039;, &amp;#039;%%%&amp;#039;), &amp;#039;|&amp;#039;, &amp;#039;@@@&amp;#039;) )&lt;br /&gt;
			end&lt;br /&gt;
			for link in mw.ustring.gmatch(params, &amp;#039;%b[]&amp;#039;) do&lt;br /&gt;
				params = mw.ustring.gsub(params, escapeString(link), mw.ustring.gsub(link, &amp;#039;|&amp;#039;, &amp;#039;@@@&amp;#039;) )&lt;br /&gt;
			end&lt;br /&gt;
			for parameter in mw.text.gsplit(params, &amp;#039;|&amp;#039;) do&lt;br /&gt;
				parts = mw.text.split(parameter, &amp;#039;=&amp;#039;)&lt;br /&gt;
				key = mw.text.trim(parts[1])&lt;br /&gt;
				value = table.concat(parts, &amp;#039;=&amp;#039;, 2)&lt;br /&gt;
				if value == &amp;#039;&amp;#039; then&lt;br /&gt;
					value = key&lt;br /&gt;
					count = count + 1&lt;br /&gt;
					key = count&lt;br /&gt;
				else&lt;br /&gt;
					value = mw.text.trim(value)&lt;br /&gt;
				end&lt;br /&gt;
				value = mw.ustring.gsub(value, &amp;#039;@@@&amp;#039;, &amp;#039;|&amp;#039;)&lt;br /&gt;
				if not blacklist and ( not flags or matchFlag(key, flags) )&lt;br /&gt;
				or blacklist and flags and not matchFlag(key, flags) then&lt;br /&gt;
					parameters[key] = value&lt;br /&gt;
				else&lt;br /&gt;
					text = removeString(text, parameter)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return parameters, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested lists out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of lists to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all lists.&lt;br /&gt;
-- @return Sequence of strings containing the wikitext of the requested lists.&lt;br /&gt;
-- @return Original wikitext minus requested lists.&lt;br /&gt;
local function getLists(text, flags)&lt;br /&gt;
	local lists = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for list in mw.ustring.gmatch(&amp;#039;\n&amp;#039; .. text .. &amp;#039;\n\n&amp;#039;, &amp;#039;\n([*#].-)\n[^*#]&amp;#039;) do&lt;br /&gt;
		count = count + 1&lt;br /&gt;
		if not blacklist and ( not flags or flags[count] )&lt;br /&gt;
		or blacklist and flags and not flags[count] then&lt;br /&gt;
			table.insert(lists, list)&lt;br /&gt;
		else&lt;br /&gt;
			text = removeString(text, list)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return lists, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested paragraphs out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of paragraphs to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all paragraphs.&lt;br /&gt;
-- @return Sequence of strings containing the wikitext of the requested paragraphs.&lt;br /&gt;
-- @return Original wikitext minus requested paragraphs.&lt;br /&gt;
local function getParagraphs(text, flags)&lt;br /&gt;
	local paragraphs = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
&lt;br /&gt;
	-- Remove non-paragraphs&lt;br /&gt;
	local elements&lt;br /&gt;
	local temp = &amp;#039;\n&amp;#039; .. text .. &amp;#039;\n&amp;#039;&lt;br /&gt;
	elements, temp = getLists(temp, 0) -- remove lists&lt;br /&gt;
	elements, temp = getFiles(temp, 0) -- remove files&lt;br /&gt;
	temp = mw.ustring.gsub(temp, &amp;#039;\n%b{}\n&amp;#039;, &amp;#039;\n%0\n&amp;#039;) -- add spacing between tables and block templates&lt;br /&gt;
	temp = mw.ustring.gsub(temp, &amp;#039;\n%b{}\n&amp;#039;, &amp;#039;\n&amp;#039;) -- remove tables and block templates&lt;br /&gt;
	temp = mw.ustring.gsub(temp, &amp;#039;\n==+[^=]+==+\n&amp;#039;, &amp;#039;\n&amp;#039;) -- remove section titles&lt;br /&gt;
	temp = mw.text.trim(temp)&lt;br /&gt;
&lt;br /&gt;
	-- Assume that anything remaining is a paragraph&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for paragraph in mw.text.gsplit(temp, &amp;#039;\n\n+&amp;#039;) do&lt;br /&gt;
		if mw.text.trim(paragraph) ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			count = count + 1&lt;br /&gt;
			if not blacklist and ( not flags or flags[count] )&lt;br /&gt;
			or blacklist and flags and not flags[count] then&lt;br /&gt;
				table.insert(paragraphs, paragraph)&lt;br /&gt;
			else&lt;br /&gt;
				text = removeString(text, paragraph)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return paragraphs, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested categories out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of categories to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all categories.&lt;br /&gt;
-- @return Sequence of strings containing the wikitext of the requested categories.&lt;br /&gt;
-- @return Original wikitext minus requested categories.&lt;br /&gt;
local function getCategories(text, flags)&lt;br /&gt;
	local categories = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
	local categoryNamespaces = getNamespaces(&amp;#039;Category&amp;#039;)&lt;br /&gt;
	local name&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for category in mw.ustring.gmatch(text, &amp;#039;%b[]&amp;#039;) do&lt;br /&gt;
		if matchAny(category, &amp;#039;%[%[%s*&amp;#039;, categoryNamespaces, &amp;#039;%s*:.*%]%]&amp;#039;) then&lt;br /&gt;
			name = mw.ustring.match(category, &amp;#039;%[%[[^:]-:([^]|]+)&amp;#039;)&lt;br /&gt;
			count = count + 1&lt;br /&gt;
			if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )&lt;br /&gt;
			or blacklist and flags and not flags[count] and not matchFlag(name, flags) then&lt;br /&gt;
				table.insert(categories, category)&lt;br /&gt;
			else&lt;br /&gt;
				text = removeString(text, category)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return categories, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested references out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of references to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all references.&lt;br /&gt;
-- @return Sequence of strings containing the wikitext of the requested references.&lt;br /&gt;
-- @return Original wikitext minus requested references.&lt;br /&gt;
local function getReferences(text, flags)&lt;br /&gt;
	local references = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
	local name&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for reference in mw.ustring.gmatch(text, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff][^&amp;gt;/]*&amp;gt;.-&amp;lt;%s*/%s*[Rr][Ee][Ff]%s*&amp;gt;&amp;#039;) do&lt;br /&gt;
		name = mw.ustring.match(reference, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff][^&amp;gt;]*name%s*=%s*[&amp;quot;\&amp;#039;]?([^&amp;quot;\&amp;#039;&amp;gt;/]+)[&amp;quot;\&amp;#039;]?[^&amp;gt;]*%s*&amp;gt;&amp;#039;)&lt;br /&gt;
		count = count + 1&lt;br /&gt;
		if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )&lt;br /&gt;
		or blacklist and flags and not flags[count] and not matchFlag(name, flags) then&lt;br /&gt;
			table.insert(references, reference)&lt;br /&gt;
		else&lt;br /&gt;
			text = removeString(text, reference)&lt;br /&gt;
			if name then&lt;br /&gt;
				for citation in mw.ustring.gmatch(text, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff][^&amp;gt;]*name%s*=%s*[&amp;quot;\&amp;#039;]?&amp;#039; .. escapeString(name) .. &amp;#039;[&amp;quot;\&amp;#039;]?[^/&amp;gt;]*/%s*&amp;gt;&amp;#039;) do&lt;br /&gt;
					text = removeString(text, citation)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return references, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the lead section out of the given wikitext.&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @return Wikitext of the lead section.&lt;br /&gt;
local function getLead(text)&lt;br /&gt;
	text = mw.ustring.gsub(&amp;#039;\n&amp;#039; .. text, &amp;#039;\n==.*&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
	text = mw.text.trim(text)&lt;br /&gt;
	if not text then return throwError(&amp;#039;lead-empty&amp;#039;) end&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the wikitext of the requested sections&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param flags Range of sections to return, for example 2 or &amp;#039;1,3-5&amp;#039;. Omit to return all references.&lt;br /&gt;
-- @return Sequence of strings containing the wikitext of the requested sections.&lt;br /&gt;
-- @return Original wikitext minus requested sections.&lt;br /&gt;
local function getSections(text, flags)&lt;br /&gt;
	local sections = {}&lt;br /&gt;
	local flags, blacklist = parseFlags(flags)&lt;br /&gt;
	local count = 0&lt;br /&gt;
	local prefix, section, suffix&lt;br /&gt;
	for title in mw.ustring.gmatch(&amp;#039;\n&amp;#039; .. text .. &amp;#039;\n==&amp;#039;, &amp;#039;\n==+%s*([^=]+)%s*==+\n&amp;#039;) do&lt;br /&gt;
		count = count + 1&lt;br /&gt;
		prefix, section, suffix = mw.ustring.match(&amp;#039;\n&amp;#039; .. text .. &amp;#039;\n==&amp;#039;, &amp;#039;\n()==+%s*&amp;#039; .. escapeString(title) .. &amp;#039;%s*==+(.-)()\n==&amp;#039;)&lt;br /&gt;
		if not blacklist and ( not flags or flags[count] or matchFlag(title, flags) )&lt;br /&gt;
		or blacklist and flags and not flags[count] and not matchFlag(title, flags) then&lt;br /&gt;
			sections[title] = section&lt;br /&gt;
		else&lt;br /&gt;
			text = mw.ustring.sub(text, 1, prefix) .. mw.ustring.sub(text, suffix)&lt;br /&gt;
			text = mw.ustring.gsub(text, &amp;#039;\n?==$&amp;#039;, &amp;#039;&amp;#039;) -- remove the trailing \n==&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return sections, text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the requested section out of the given wikitext (including subsections).&lt;br /&gt;
-- @param text Required. Wikitext to parse.&lt;br /&gt;
-- @param section Required. Title of the section to get (in wikitext), for example &amp;#039;History&amp;#039; or &amp;#039;History of [[Athens]]&amp;#039;.&lt;br /&gt;
-- @return Wikitext of the requested section.&lt;br /&gt;
local function getSection(text, section)&lt;br /&gt;
	section = mw.text.trim(section)&lt;br /&gt;
	local escapedSection = escapeString(section)&lt;br /&gt;
	-- First check if the section title matches a &amp;lt;section&amp;gt; tag&lt;br /&gt;
	if mw.ustring.find(text, &amp;#039;&amp;lt;%s*[Ss]ection%s+begin%s*=%s*[&amp;quot;\&amp;#039;]?%s*&amp;#039; .. escapedSection .. &amp;#039;%s*[&amp;quot;\&amp;#039;]?%s*/&amp;gt;&amp;#039;) then -- avoid expensive search if possible&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;#039;&amp;lt;%s*[Ss]ection%s+end=%s*[&amp;quot;\&amp;#039;]?%s*&amp;#039;.. escapedSection ..&amp;#039;%s*[&amp;quot;\&amp;#039;]?%s*/&amp;gt;.-&amp;lt;%s*[Ss]ection%s+begin%s*=%s*[&amp;quot;\&amp;#039;]?%s*&amp;#039; .. escapedSection .. &amp;#039;%s*[&amp;quot;\&amp;#039;]?%s*/&amp;gt;&amp;#039;, &amp;#039;&amp;#039;) -- remove text between section tags&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;#039;^.-&amp;lt;%s*[Ss]ection%s+begin%s*=%s*[&amp;quot;\&amp;#039;]?%s*&amp;#039; .. escapedSection .. &amp;#039;%s*[&amp;quot;\&amp;#039;]?%s*/&amp;gt;&amp;#039;, &amp;#039;&amp;#039;) -- remove text before first section tag&lt;br /&gt;
		text = mw.ustring.gsub(text, &amp;#039;&amp;lt;%s*[Ss]ection%s+end=%s*[&amp;quot;\&amp;#039;]?%s*&amp;#039;.. escapedSection ..&amp;#039;%s*[&amp;quot;\&amp;#039;]?%s*/&amp;gt;.*&amp;#039;, &amp;#039;&amp;#039;) -- remove text after last section tag&lt;br /&gt;
		text = mw.text.trim(text)&lt;br /&gt;
		if text == &amp;#039;&amp;#039; then return throwError(&amp;#039;section-tag-empty&amp;#039;, section) end&lt;br /&gt;
		return text&lt;br /&gt;
	end&lt;br /&gt;
	local level, text = mw.ustring.match(&amp;#039;\n&amp;#039; .. text .. &amp;#039;\n&amp;#039;, &amp;#039;\n(==+)%s*&amp;#039; .. escapedSection .. &amp;#039;%s*==.-\n(.*)&amp;#039;)&lt;br /&gt;
	if not text then return throwError(&amp;#039;section-not-found&amp;#039;, section) end&lt;br /&gt;
	local nextSection = &amp;#039;\n==&amp;#039; .. mw.ustring.rep(&amp;#039;=?&amp;#039;, #level - 2) .. &amp;#039;[^=].*&amp;#039;&lt;br /&gt;
	text = mw.ustring.gsub(text, nextSection, &amp;#039;&amp;#039;) -- remove later sections with headings at this level or higher&lt;br /&gt;
	text = mw.text.trim(text)&lt;br /&gt;
	if text == &amp;#039;&amp;#039; then return throwError(&amp;#039;section-empty&amp;#039;, section) end&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Replace the first call to each reference defined outside of the text for the full reference, to prevent undefined references&lt;br /&gt;
-- Then prefix the page title to the reference names to prevent conflicts&lt;br /&gt;
-- that is, replace &amp;lt;ref name=&amp;quot;Foo&amp;quot;&amp;gt; for &amp;lt;ref name=&amp;quot;Title of the article Foo&amp;quot;&amp;gt;&lt;br /&gt;
-- and also &amp;lt;ref name=&amp;quot;Foo&amp;quot; /&amp;gt; for &amp;lt;ref name=&amp;quot;Title of the article Foo&amp;quot; /&amp;gt;&lt;br /&gt;
-- also remove reference groups: &amp;lt;ref name=&amp;quot;Foo&amp;quot; group=&amp;quot;Bar&amp;quot;&amp;gt; for &amp;lt;ref name=&amp;quot;Title of the article Foo&amp;quot;&amp;gt;&lt;br /&gt;
-- and &amp;lt;ref group=&amp;quot;Bar&amp;quot;&amp;gt; for &amp;lt;ref&amp;gt;&lt;br /&gt;
-- @todo The current regex may fail in cases with both kinds of quotes, like &amp;lt;ref name=&amp;quot;Darwin&amp;#039;s book&amp;quot;&amp;gt;&lt;br /&gt;
local function fixReferences(text, page, full)&lt;br /&gt;
	if not full then full = getText(page) end&lt;br /&gt;
	local refNames = {}&lt;br /&gt;
	local refName&lt;br /&gt;
	local refBody&lt;br /&gt;
	local position = 1&lt;br /&gt;
	while position &amp;lt; mw.ustring.len(text) do&lt;br /&gt;
		refName, position = mw.ustring.match(text, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff][^&amp;gt;]*name%s*=%s*[&amp;quot;\&amp;#039;]?([^&amp;quot;\&amp;#039;&amp;gt;]+)[&amp;quot;\&amp;#039;]?[^&amp;gt;]*/%s*&amp;gt;()&amp;#039;, position)&lt;br /&gt;
		if refName then&lt;br /&gt;
			refName = mw.text.trim(refName)&lt;br /&gt;
			if not refNames[refName] then -- make sure we process each ref name only once&lt;br /&gt;
				table.insert(refNames, refName)&lt;br /&gt;
				refName = escapeString(refName)&lt;br /&gt;
				refBody = mw.ustring.match(text, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff][^&amp;gt;]*name%s*=%s*[&amp;quot;\&amp;#039;]?%s*&amp;#039; .. refName .. &amp;#039;%s*[&amp;quot;\&amp;#039;]?[^&amp;gt;/]*&amp;gt;.-&amp;lt;%s*/%s*[Rr][Ee][Ff]%s*&amp;gt;&amp;#039;)&lt;br /&gt;
				if not refBody then -- the ref body is not in the excerpt&lt;br /&gt;
					refBody = mw.ustring.match(full, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff][^&amp;gt;]*name%s*=%s*[&amp;quot;\&amp;#039;]?%s*&amp;#039; .. refName .. &amp;#039;%s*[&amp;quot;\&amp;#039;]?[^/&amp;gt;]*&amp;gt;.-&amp;lt;%s*/%s*[Rr][Ee][Ff]%s*&amp;gt;&amp;#039;)&lt;br /&gt;
					if refBody then -- the ref body was found elsewhere&lt;br /&gt;
						text = mw.ustring.gsub(text, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff][^&amp;gt;]*name%s*=%s*[&amp;quot;\&amp;#039;]?%s*&amp;#039; .. refName .. &amp;#039;%s*[&amp;quot;\&amp;#039;]?[^&amp;gt;]*/?%s*&amp;gt;&amp;#039;, mw.ustring.gsub(refBody, &amp;#039;%%&amp;#039;, &amp;#039;%%%%&amp;#039;), 1)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			position = mw.ustring.len(text)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff][^&amp;gt;]*name%s*=%s*[&amp;quot;\&amp;#039;]?([^&amp;quot;\&amp;#039;&amp;gt;/]+)[&amp;quot;\&amp;#039;]?[^&amp;gt;/]*(/?)%s*&amp;gt;&amp;#039;, &amp;#039;&amp;lt;ref name=&amp;quot;&amp;#039; .. page .. &amp;#039; %1&amp;quot;%2&amp;gt;&amp;#039;)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;&amp;lt;%s*[Rr][Ee][Ff]%s*group%s*=%s*[&amp;quot;\&amp;#039;]?[^&amp;quot;\&amp;#039;&amp;gt;/]+[&amp;quot;\&amp;#039;]%s*&amp;gt;&amp;#039;, &amp;#039;&amp;lt;ref&amp;gt;&amp;#039;)&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Replace the bold title or synonym near the start of the page by a link to the page&lt;br /&gt;
function linkBold(text, page)&lt;br /&gt;
	local lang = mw.language.getContentLanguage()&lt;br /&gt;
	local position = mw.ustring.find(text, &amp;quot;&amp;#039;&amp;#039;&amp;#039;&amp;quot; .. lang:ucfirst(page) .. &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(page) .. &amp;quot;&amp;#039;&amp;#039;&amp;#039;&amp;quot;, 1, true) -- plain search: special characters in page represent themselves&lt;br /&gt;
	if position then&lt;br /&gt;
		local length = mw.ustring.len(page)&lt;br /&gt;
		text = mw.ustring.sub(text, 1, position + 2) .. &amp;quot;[[&amp;quot; .. mw.ustring.sub(text, position + 3, position + length + 2) .. &amp;quot;]]&amp;quot; .. mw.ustring.sub(text, position + length + 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 not mw.ustring.find(b, &amp;quot;%[&amp;quot;) and not mw.ustring.find(b, &amp;quot;%{&amp;quot;) then -- if not wikilinked or some weird template&lt;br /&gt;
				return &amp;quot;&amp;#039;&amp;#039;&amp;#039;[[&amp;quot; .. page .. &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;[[page|Foo]]&amp;#039;&amp;#039;&amp;#039;&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;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Remove non-free files.&lt;br /&gt;
-- @param text Required. Wikitext to clean.&lt;br /&gt;
-- @return Clean wikitext.&lt;br /&gt;
local function removeNonFreeFiles(text)&lt;br /&gt;
	local fileNamespaces = getNamespaces(&amp;#039;File&amp;#039;)&lt;br /&gt;
	local fileName&lt;br /&gt;
	local fileDescription&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	for file in mw.ustring.gmatch(text, &amp;#039;%b[]&amp;#039;) do&lt;br /&gt;
		if matchAny(file, &amp;#039;%[%[%s*&amp;#039;, fileNamespaces, &amp;#039;%s*:.*%]%]&amp;#039;) then&lt;br /&gt;
			fileName = &amp;#039;File:&amp;#039; .. mw.ustring.match(file, &amp;#039;%[%[[^:]-:([^]|]+)&amp;#039;)&lt;br /&gt;
			fileDescription, fileName = getText(fileName)&lt;br /&gt;
			if fileName then&lt;br /&gt;
				if not fileDescription or fileDescription == &amp;#039;&amp;#039; then&lt;br /&gt;
					fileDescription = frame:preprocess(&amp;#039;{{&amp;#039; .. fileName .. &amp;#039;}}&amp;#039;) -- try Commons&lt;br /&gt;
				end&lt;br /&gt;
				if fileDescription and mw.ustring.match(fileDescription, &amp;#039;[Nn]on%-free&amp;#039;) then&lt;br /&gt;
					text = removeString(text, file)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Remove any self links&lt;br /&gt;
function removeSelfLinks(text)&lt;br /&gt;
	local lang = mw.language.getContentLanguage()&lt;br /&gt;
	local page = escapeString( mw.title.getCurrentTitle().prefixedText )&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;%[%[(&amp;#039; .. lang:ucfirst(page) .. &amp;#039;)%]%]&amp;#039;, &amp;#039;%1&amp;#039;)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;%[%[(&amp;#039; .. lang:lcfirst(page) .. &amp;#039;)%]%]&amp;#039;, &amp;#039;%1&amp;#039;)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;%[%[&amp;#039; .. lang:ucfirst(page) .. &amp;#039;|([^]]+)%]%]&amp;#039;, &amp;#039;%1&amp;#039;)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;%[%[&amp;#039; .. lang:lcfirst(page) .. &amp;#039;|([^]]+)%]%]&amp;#039;, &amp;#039;%1&amp;#039;)&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Remove all wikilinks&lt;br /&gt;
function removeLinks(text)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;%[%[[^|]+|([^]]+)%]%]&amp;#039;, &amp;#039;%1&amp;#039;)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;%[%[([^]]+)%]%]&amp;#039;, &amp;#039;%1&amp;#039;)&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Remove HTML comments&lt;br /&gt;
function removeComments(text)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;&amp;lt;!%-%-.-%-%-&amp;gt;&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Remove behavior switches, such as __NOTOC__&lt;br /&gt;
function removeBehaviorSwitches(text)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;__[A-Z]+__&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Remove bold text&lt;br /&gt;
function removeBold(text)&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;&amp;#039;&amp;#039;&amp;#039;&amp;quot;, &amp;#039;&amp;#039;)&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Main function for modules&lt;br /&gt;
local function get(page, options)&lt;br /&gt;
	if not options then options = {} end&lt;br /&gt;
&lt;br /&gt;
	if not page then return throwError(&amp;#039;no-page&amp;#039;) end&lt;br /&gt;
	page = mw.text.trim(page)&lt;br /&gt;
	if page == &amp;#039;&amp;#039; then return throwError(&amp;#039;no-page&amp;#039;) end&lt;br /&gt;
	local page, hash, section = mw.ustring.match(page, &amp;#039;([^#]+)(#?)([^#]*)&amp;#039;)&lt;br /&gt;
	local text, page = getText(page, options.noFollow)&lt;br /&gt;
	if not page then return throwError(&amp;#039;no-page&amp;#039;) end&lt;br /&gt;
	if not text then return throwError(&amp;#039;page-not-found&amp;#039;, page) end&lt;br /&gt;
	local full = text -- save the full text for fixReferences below&lt;br /&gt;
&lt;br /&gt;
	-- Get the requested section&lt;br /&gt;
	if truthy(section) then&lt;br /&gt;
		text = getSection(text, section)&lt;br /&gt;
	elseif truthy(hash) then&lt;br /&gt;
		text = getLead(text)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Keep only the requested elements&lt;br /&gt;
	local elements&lt;br /&gt;
	if options.only then&lt;br /&gt;
		if options.only == &amp;#039;sections&amp;#039; then elements = getSections(text, options.sections) end&lt;br /&gt;
		if options.only == &amp;#039;lists&amp;#039; then elements = getLists(text, options.lists) end&lt;br /&gt;
		if options.only == &amp;#039;files&amp;#039; then elements = getFiles(text, options.files) end&lt;br /&gt;
		if options.only == &amp;#039;tables&amp;#039; then elements = getTables(text, options.tables) end&lt;br /&gt;
		if options.only == &amp;#039;templates&amp;#039; then elements = getTemplates(text, options.templates) end&lt;br /&gt;
		if options.only == &amp;#039;parameters&amp;#039; then elements = getParameters(text, options.parameters) end&lt;br /&gt;
		if options.only == &amp;#039;paragraphs&amp;#039; then elements = getParagraphs(text, options.paragraphs) end&lt;br /&gt;
		if options.only == &amp;#039;categories&amp;#039; then elements = getCategories(text, options.categories) end&lt;br /&gt;
		if options.only == &amp;#039;references&amp;#039; then elements = getReferences(text, options.references) end&lt;br /&gt;
		text = &amp;#039;&amp;#039;&lt;br /&gt;
		if elements then&lt;br /&gt;
			for key, element in pairs(elements) do&lt;br /&gt;
				text = text .. &amp;#039;\n&amp;#039; .. element .. &amp;#039;\n&amp;#039;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Filter the requested elements&lt;br /&gt;
	if options.sections and options.only ~= &amp;#039;sections&amp;#039; then elements, text = getSections(text, options.sections) end&lt;br /&gt;
	if options.lists and options.only ~= &amp;#039;lists&amp;#039; then elements, text = getLists(text, options.lists) end&lt;br /&gt;
	if options.files and options.only ~= &amp;#039;files&amp;#039; then elements, text = getFiles(text, options.files) end&lt;br /&gt;
	if options.tables and options.only ~= &amp;#039;tables&amp;#039; then elements, text = getTables(text, options.tables) end&lt;br /&gt;
	if options.templates and options.only ~= &amp;#039;templates&amp;#039; then elements, text = getTemplates(text, options.templates) end&lt;br /&gt;
	if options.parameters and options.only ~= &amp;#039;parameters&amp;#039; then elements, text = getParameters(text, options.parameters) end&lt;br /&gt;
	if options.paragraphs and options.only ~= &amp;#039;paragraphs&amp;#039; then elements, text = getParagraphs(text, options.paragraphs) end&lt;br /&gt;
	if options.categories and options.only ~= &amp;#039;categories&amp;#039; then elements, text = getCategories(text, options.categories) end&lt;br /&gt;
	if options.references and options.only ~= &amp;#039;references&amp;#039; then elements, text = getReferences(text, options.references) end&lt;br /&gt;
&lt;br /&gt;
	-- Misc options&lt;br /&gt;
	if truthy(options.fixReferences) then text = fixReferences(text, page, full) end&lt;br /&gt;
	if truthy(options.linkBold) then text = linkBold(text, page) end&lt;br /&gt;
	if truthy(options.noBold) then text = removeBold(text) end&lt;br /&gt;
	if truthy(options.noLinks) then text = removeLinks(text) end&lt;br /&gt;
	if truthy(options.noSelfLinks) then text = removeSelfLinks(text) end&lt;br /&gt;
	if truthy(options.noNonFreeFiles) then text = removeNonFreeFiles(text) end&lt;br /&gt;
	if truthy(options.noBehaviorSwitches) then text = removeBehaviorSwitches(text) end&lt;br /&gt;
	if truthy(options.noComments) then text = removeComments(text) end&lt;br /&gt;
&lt;br /&gt;
	-- Remove multiple newlines left over from removing elements&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;#039;\n\n\n+&amp;#039;, &amp;#039;\n\n&amp;#039;)&lt;br /&gt;
	text = mw.text.trim(text)&lt;br /&gt;
&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Main invocation function for templates&lt;br /&gt;
local function main(frame)&lt;br /&gt;
	local args = parseArgs(frame)&lt;br /&gt;
	local page = args[1]&lt;br /&gt;
	local ok, text = pcall(get, page, args)&lt;br /&gt;
	if not ok then return getError(text) end&lt;br /&gt;
	return frame:preprocess(text)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Entry points for templates&lt;br /&gt;
function p.main(frame) return main(frame) end&lt;br /&gt;
&lt;br /&gt;
-- Entry points for modules&lt;br /&gt;
function p.get(page, options) return get(page, options) end&lt;br /&gt;
function p.getText(page, noFollow) return getText(page, noFollow) end&lt;br /&gt;
function p.getLead(text) return getLead(text) end&lt;br /&gt;
function p.getSection(text, section) return getSection(text, section) end&lt;br /&gt;
function p.getSections(text, flags) return getSections(text, flags) end&lt;br /&gt;
function p.getParagraphs(text, flags) return getParagraphs(text, flags) end&lt;br /&gt;
function p.getParameters(text, flags) return getParameters(text, flags) end&lt;br /&gt;
function p.getCategories(text, flags) return getCategories(text, flags) end&lt;br /&gt;
function p.getReferences(text, flags) return getReferences(text, flags) end&lt;br /&gt;
function p.getTemplates(text, flags) return getTemplates(text, flags) end&lt;br /&gt;
function p.getTables(text, flags) return getTables(text, flags) end&lt;br /&gt;
function p.getLists(text, flags) return getLists(text, flags) end&lt;br /&gt;
function p.getFiles(text, flags) return getFiles(text, flags) end&lt;br /&gt;
function p.getError(message, value) return getError(message, value) end&lt;br /&gt;
&lt;br /&gt;
-- Expose handy methods&lt;br /&gt;
function p.truthy(value) return truthy(value) end&lt;br /&gt;
function p.parseArgs(frame) return parseArgs(frame) end&lt;br /&gt;
function p.matchAny(text, pre, list, post, init) return matchAny(text, pre, list, post, init) end&lt;br /&gt;
function p.matchFlag(value, flags) return matchFlag(value, flags) end&lt;br /&gt;
function p.getNamespaces(name) return getNamespaces(name) end&lt;br /&gt;
function p.removeBold(text) return removeBold(text) end&lt;br /&gt;
function p.removeLinks(text) return removeLinks(text) end&lt;br /&gt;
function p.removeSelfLinks(text) return removeSelfLinks(text) end&lt;br /&gt;
function p.removeNonFreeFiles(text) return removeNonFreeFiles(text) end&lt;br /&gt;
function p.removeBehaviorSwitches(text) return removeBehaviorSwitches(text) end&lt;br /&gt;
function p.removeComments(text) return removeComments(text) end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Bigwig</name></author>
	</entry>
</feed>