<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.statsape.com/index.php?action=history&amp;feed=atom&amp;title=%E6%A8%A1%E5%9D%97%3ADPLlua</id>
	<title>模块:DPLlua - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.statsape.com/index.php?action=history&amp;feed=atom&amp;title=%E6%A8%A1%E5%9D%97%3ADPLlua"/>
	<link rel="alternate" type="text/html" href="https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:DPLlua&amp;action=history"/>
	<updated>2026-04-04T09:37:23Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:DPLlua&amp;diff=505&amp;oldid=prev</id>
		<title>Zeroclanzhang：​创建页面，内容为“-- &lt;nowiki&gt; local dpl = {} local libraryUtil = require( &#039;libraryUtil&#039; ) local hasContent = require( &#039;Module:Paramtest&#039; ).has_content local checkType = libraryUtil.checkType local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg  dpl.pipe = &#039;¦&#039; local dataContentMarker = &#039;`#@@#`&#039; local allIncludedParamNames = {}  -- Custom function for splitting a string because mw.text.split() is waaay too slow local function split( str, pattern, plain ) 	local res = {}…”</title>
		<link rel="alternate" type="text/html" href="https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:DPLlua&amp;diff=505&amp;oldid=prev"/>
		<updated>2023-07-13T14:13:02Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“-- &amp;lt;nowiki&amp;gt; local dpl = {} local libraryUtil = require( &amp;#039;libraryUtil&amp;#039; ) local hasContent = require( &amp;#039;Module:Paramtest&amp;#039; ).has_content local checkType = libraryUtil.checkType local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg  dpl.pipe = &amp;#039;¦&amp;#039; local dataContentMarker = &amp;#039;`#@@#`&amp;#039; local allIncludedParamNames = {}  -- Custom function for splitting a string because mw.text.split() is waaay too slow local function split( str, pattern, plain ) 	local res = {}…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- &amp;lt;nowiki&amp;gt;&lt;br /&gt;
local dpl = {}&lt;br /&gt;
local libraryUtil = require( &amp;#039;libraryUtil&amp;#039; )&lt;br /&gt;
local hasContent = require( &amp;#039;Module:Paramtest&amp;#039; ).has_content&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg&lt;br /&gt;
&lt;br /&gt;
dpl.pipe = &amp;#039;¦&amp;#039;&lt;br /&gt;
local dataContentMarker = &amp;#039;`#@@#`&amp;#039;&lt;br /&gt;
local allIncludedParamNames = {}&lt;br /&gt;
&lt;br /&gt;
-- Custom function for splitting a string because mw.text.split() is waaay too slow&lt;br /&gt;
local function split( str, pattern, plain )&lt;br /&gt;
	local res = {}&lt;br /&gt;
	local continue = true&lt;br /&gt;
	local startIndex = 1&lt;br /&gt;
&lt;br /&gt;
	while continue do&lt;br /&gt;
		local i, j = string.find( str, pattern, startIndex, plain )&lt;br /&gt;
		if i then&lt;br /&gt;
			table.insert( res, string.sub( str, startIndex, i-1 ) )&lt;br /&gt;
			startIndex = j + 1&lt;br /&gt;
		else&lt;br /&gt;
			table.insert( res, string.sub( str, startIndex ) )&lt;br /&gt;
			continue = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return res&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Also custom function for speed&lt;br /&gt;
local function trim( str )&lt;br /&gt;
	return (string.gsub( str, &amp;#039;^%s+&amp;#039;, &amp;#039;&amp;#039; ):gsub( &amp;#039;%s+$&amp;#039;, &amp;#039;&amp;#039; ))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function mergeItem( tbl, key, item )&lt;br /&gt;
	if type( tbl[key] ) == &amp;#039;table&amp;#039; and type( item ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		for k in pairs( tbl[key] ) do&lt;br /&gt;
			mergeItem( tbl[key], k, item[k] )&lt;br /&gt;
		end&lt;br /&gt;
	elseif type( tbl[key] ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		table.insert( tbl[key], item )&lt;br /&gt;
	else&lt;br /&gt;
		tbl[key] = { tbl[key], item }&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local escapeChars = {&lt;br /&gt;
	[&amp;#039;{&amp;#039;] = &amp;#039;&amp;amp;#123;&amp;#039;,&lt;br /&gt;
	[&amp;#039;}&amp;#039;] = &amp;#039;&amp;amp;#125;&amp;#039;,&lt;br /&gt;
	[&amp;#039;[&amp;#039;] = &amp;#039;&amp;amp;#91;&amp;#039;,&lt;br /&gt;
	[&amp;#039;]&amp;#039;] = &amp;#039;&amp;amp;#93;&amp;#039;,&lt;br /&gt;
	[&amp;#039;|&amp;#039;] = &amp;#039;&amp;amp;#124;&amp;#039;,&lt;br /&gt;
	[&amp;#039;-&amp;#039;] = &amp;#039;&amp;amp;#8208;&amp;#039;&lt;br /&gt;
}&lt;br /&gt;
local function escape( str )&lt;br /&gt;
	return (string.gsub( str, &amp;#039;[{}%[%]|%-]&amp;#039;, escapeChars ))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local unEscapeChars = {&lt;br /&gt;
	[&amp;#039;&amp;amp;#123;&amp;#039;] = &amp;#039;{&amp;#039;,&lt;br /&gt;
	[&amp;#039;&amp;amp;#125;&amp;#039;] = &amp;#039;}&amp;#039;,&lt;br /&gt;
	[&amp;#039;&amp;amp;#91;&amp;#039;] = &amp;#039;[&amp;#039;,&lt;br /&gt;
	[&amp;#039;&amp;amp;#93;&amp;#039;] = &amp;#039;]&amp;#039;,&lt;br /&gt;
	[&amp;#039;&amp;amp;#124;&amp;#039;] = &amp;#039;|&amp;#039;,&lt;br /&gt;
	[&amp;#039;&amp;amp;#8208;&amp;#039;] = &amp;#039;-&amp;#039;&lt;br /&gt;
}&lt;br /&gt;
local function unEscape( str )&lt;br /&gt;
	return (string.gsub( str, &amp;#039;&amp;amp;#%d+;&amp;#039;, unEscapeChars ))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function fixCurlyBrackets( str )&lt;br /&gt;
	-- the \226\157\180\181 are used to match ❴ (U+2774) and ❵ (U+2775) wich are 3 bytes long (UTF-8) so&lt;br /&gt;
	-- we can&amp;#039;t use them directly inside [] patterns. Ustring would fix this but it&amp;#039;s way too slow.&lt;br /&gt;
	return (string.gsub( str, &amp;#039;\226\157[\180\181]&amp;#039;, { [&amp;#039;❴&amp;#039;] = &amp;#039;{&amp;#039;, [&amp;#039;❵&amp;#039;] = &amp;#039;}&amp;#039; } ))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function removeFormattingSettings( query )&lt;br /&gt;
	local toRemove = {&lt;br /&gt;
		&amp;#039;mode&amp;#039;,&lt;br /&gt;
		&amp;#039;table&amp;#039;,&lt;br /&gt;
		&amp;#039;tablerow&amp;#039;,&lt;br /&gt;
		&amp;#039;tablesortcol&amp;#039;,&lt;br /&gt;
		&amp;#039;headingmode&amp;#039;,&lt;br /&gt;
		&amp;#039;headingcount&amp;#039;,&lt;br /&gt;
		&amp;#039;listattr&amp;#039;,&lt;br /&gt;
		&amp;#039;itemattr&amp;#039;,&lt;br /&gt;
		&amp;#039;hlistattr&amp;#039;,&lt;br /&gt;
		&amp;#039;hitemattr&amp;#039;,&lt;br /&gt;
		&amp;#039;userdateformat&amp;#039;,&lt;br /&gt;
		&amp;#039;shownamespace&amp;#039;,&lt;br /&gt;
		&amp;#039;escapelinks&amp;#039;,&lt;br /&gt;
		&amp;#039;titlemaxlength&amp;#039;,&lt;br /&gt;
		&amp;#039;replaceintitle&amp;#039;,&lt;br /&gt;
		&amp;#039;columns&amp;#039;,&lt;br /&gt;
		&amp;#039;rows&amp;#039;,&lt;br /&gt;
		&amp;#039;rowsize&amp;#039;,&lt;br /&gt;
		&amp;#039;rowcolformat&amp;#039;,&lt;br /&gt;
		&amp;#039;resultsheader&amp;#039;,&lt;br /&gt;
		&amp;#039;resultsfooter&amp;#039;,&lt;br /&gt;
		&amp;#039;oneresultheader&amp;#039;,&lt;br /&gt;
		&amp;#039;oneresultfooter&amp;#039;,&lt;br /&gt;
		&amp;#039;noresultsheader&amp;#039;,&lt;br /&gt;
		&amp;#039;suppresserrors&amp;#039;,&lt;br /&gt;
		&amp;#039;noresultsfooter&amp;#039;,&lt;br /&gt;
		&amp;#039;format&amp;#039;,&lt;br /&gt;
		&amp;#039;groupMultiTemplateResults&amp;#039;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for _, k in ipairs( toRemove ) do&lt;br /&gt;
		query[k] = nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatInclude( query )&lt;br /&gt;
	checkTypeForNamedArg( &amp;#039;Module:DPLlua.ask&amp;#039;, &amp;#039;include&amp;#039;, query, &amp;#039;string&amp;#039; )&lt;br /&gt;
	query = split( query, &amp;#039;,&amp;#039;, true )&lt;br /&gt;
	local includedParamNames = {}&lt;br /&gt;
	local sectionAttributes = {}&lt;br /&gt;
&lt;br /&gt;
	for i = 1, #query do&lt;br /&gt;
		if query[i]:match( &amp;#039;%b{}&amp;#039; ) then -- Check if we are including a template&lt;br /&gt;
			local templateName, extra = query[i]:match( &amp;#039;{(.-)[¦|}](.*)&amp;#039; )&lt;br /&gt;
			if hasContent( extra ) then&lt;br /&gt;
				local phantomTemplateName = extra:match( &amp;#039;^(.-)}&amp;#039; ) or extra:match( &amp;#039;^[./].+&amp;#039; )&lt;br /&gt;
				local phantomTemplatePrefix = extra:match( &amp;#039;^(.-)}&amp;#039; ) and &amp;#039;&amp;#039; or templateName&lt;br /&gt;
				local params = extra:gsub( &amp;#039;^.-}&amp;#039;, &amp;#039;&amp;#039; ):gsub( &amp;#039;^[./].+&amp;#039;, &amp;#039;&amp;#039; ):gsub( &amp;#039;:%-&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
				local sur = hasContent( phantomTemplateName ) and (&amp;#039;¦&amp;#039; .. phantomTemplatePrefix .. phantomTemplateName) or &amp;#039;&amp;#039;&lt;br /&gt;
				query[i] = string.format( &amp;#039;{%s%s}%s&amp;#039;, templateName, sur, params )&lt;br /&gt;
&lt;br /&gt;
				if hasContent( phantomTemplateName ) then&lt;br /&gt;
					table.insert( includedParamNames, { name=phantomTemplatePrefix..phantomTemplateName, isTemplate=true, hasPhantomTemplate=true } )&lt;br /&gt;
					table.insert( sectionAttributes, { hasPhantomTemplate=true } )&lt;br /&gt;
				else&lt;br /&gt;
					for param in params:gmatch( &amp;#039;:([^:]*)&amp;#039; ) do&lt;br /&gt;
						param = trim( param )&lt;br /&gt;
						table.insert( includedParamNames, { name=templateName, isTemplate=true, param=param } )&lt;br /&gt;
					end&lt;br /&gt;
					table.insert( sectionAttributes, { hasPhantomTemplate=false } )&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				query[i] = string.format( &amp;#039;{%s¦DPLlua helper}&amp;#039;, templateName ) -- Use a helper template to get all the parameters of our included template&lt;br /&gt;
				table.insert( includedParamNames, { name=templateName, isTemplate=true, includeAll=true } )&lt;br /&gt;
				table.insert( sectionAttributes, { hasPhantomTemplate=false } )&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			table.insert( includedParamNames, { name=trim( query[i] ) } )&lt;br /&gt;
			table.insert( sectionAttributes, { hasPhantomTemplate=false } )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat( query, &amp;#039;,&amp;#039; ), includedParamNames, sectionAttributes&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatDpl( query )&lt;br /&gt;
	local queries = {}&lt;br /&gt;
	local count = query.count or 500&lt;br /&gt;
	local offset = query.offset or 0&lt;br /&gt;
	local usesInclude = false&lt;br /&gt;
	local includedParamNames = {}&lt;br /&gt;
	local sectionAttributes&lt;br /&gt;
	query.count = nil&lt;br /&gt;
	query.offset = nil&lt;br /&gt;
&lt;br /&gt;
	-- Use table format so we can place dataContentMarkers around each included parameter. The secseparator&lt;br /&gt;
	-- is needed to add dataContentMarkers when a phantom template is used&lt;br /&gt;
	local dplStringInclude =&lt;br /&gt;
[=[&lt;br /&gt;
{{#dpl:&lt;br /&gt;
|noresultsheader=@@&lt;br /&gt;
|count=%s&lt;br /&gt;
|offset=%s&lt;br /&gt;
|%s&lt;br /&gt;
|table=,&lt;br /&gt;
|listseparators=,\n¦-\n¦[[%%PAGE%%¦]],,&lt;br /&gt;
|tablerow=%s&lt;br /&gt;
|secseparators=%s&lt;br /&gt;
}}]=]&lt;br /&gt;
&lt;br /&gt;
	-- Table format requires an include statement so we use format instead.&lt;br /&gt;
	-- This is also a lot faster than adding an empty include statement&lt;br /&gt;
	local dplStringNoInclude =&lt;br /&gt;
[=[&lt;br /&gt;
{{#dpl:&lt;br /&gt;
|noresultsheader=@@&lt;br /&gt;
|count=%s&lt;br /&gt;
|offset=%s&lt;br /&gt;
|%s&lt;br /&gt;
|format=,¦-¦[[%%PAGE%%¦]],,&lt;br /&gt;
}}]=]&lt;br /&gt;
&lt;br /&gt;
	-- Auto generate more than one dpl if count &amp;gt; 500&lt;br /&gt;
	-- The results of these are later combined&lt;br /&gt;
	for i = 1, math.ceil( count / 500 ) do&lt;br /&gt;
		local params = {}&lt;br /&gt;
&lt;br /&gt;
		for k, v in pairs( query ) do&lt;br /&gt;
			if k == &amp;#039;include&amp;#039; then&lt;br /&gt;
				v, includedParamNames, sectionAttributes = formatInclude( v )&lt;br /&gt;
				usesInclude =  true&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if type( v ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
				for _, x in ipairs( v ) do&lt;br /&gt;
					table.insert( params, k .. &amp;#039;=&amp;#039; .. tostring( x ):gsub( &amp;#039;|&amp;#039;, &amp;#039;¦&amp;#039; ) )&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				table.insert( params, k .. &amp;#039;=&amp;#039; .. tostring( v ):gsub( &amp;#039;|&amp;#039;, &amp;#039;¦&amp;#039; ) )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if usesInclude then&lt;br /&gt;
			local secseparators = &amp;#039;&amp;#039;&lt;br /&gt;
			for _, v in ipairs( sectionAttributes ) do&lt;br /&gt;
				if v.hasPhantomTemplate then&lt;br /&gt;
					-- Phantom templates need this because they ignore tablerow formatting&lt;br /&gt;
					secseparators = secseparators .. &amp;#039;¶¦&amp;#039; .. dataContentMarker .. &amp;#039;,&amp;#039; .. dataContentMarker .. &amp;#039;,&amp;#039;&lt;br /&gt;
				else&lt;br /&gt;
					secseparators = secseparators .. &amp;#039;¶¦,,&amp;#039;&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			table.insert( queries, string.format(&lt;br /&gt;
				dplStringInclude,&lt;br /&gt;
				count &amp;gt; 500 and 500 or count,&lt;br /&gt;
				offset,&lt;br /&gt;
				table.concat( params, &amp;#039;\n|&amp;#039; ),&lt;br /&gt;
				string.rep( dataContentMarker..&amp;#039;%%&amp;#039;..dataContentMarker..&amp;#039;,&amp;#039;, #includedParamNames ),&lt;br /&gt;
				secseparators&lt;br /&gt;
			) )&lt;br /&gt;
		else&lt;br /&gt;
			table.insert( queries, string.format(&lt;br /&gt;
				dplStringNoInclude,&lt;br /&gt;
				count &amp;gt; 500 and 500 or count,&lt;br /&gt;
				offset,&lt;br /&gt;
				table.concat( params, &amp;#039;\n|&amp;#039; )&lt;br /&gt;
			) )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		count = count - 500&lt;br /&gt;
		offset = offset + 500&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	table.insert( allIncludedParamNames, includedParamNames )&lt;br /&gt;
	return table.concat( queries )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function toTable( query, groupMultiTemplateResults )&lt;br /&gt;
	local includedParamNames = table.remove( allIncludedParamNames, 1 )&lt;br /&gt;
	local usesInclude = #includedParamNames &amp;gt; 0&lt;br /&gt;
	local res = {}&lt;br /&gt;
&lt;br /&gt;
	query = query:gsub( &amp;#039;&amp;lt;p&amp;gt;Extension:DynamicPageList .-&amp;lt;/p&amp;gt;&amp;#039;, function(item) res.error = item; return &amp;#039;&amp;#039; end )&lt;br /&gt;
&lt;br /&gt;
	if query:find( &amp;#039;^@@&amp;#039; ) then -- @@ is used when no result is found&lt;br /&gt;
		return res&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if usesInclude then&lt;br /&gt;
		query = query:gsub( dataContentMarker..&amp;#039;(.-)&amp;#039;..dataContentMarker, escape )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	query = trim( query )&lt;br /&gt;
	query = split( query, &amp;#039;|-&amp;#039;, true ) -- Results of the returned pages are separated by |-&lt;br /&gt;
&lt;br /&gt;
	for _, v in ipairs( query ) do&lt;br /&gt;
		if hasContent( v ) and not v:find( &amp;#039;^@@&amp;#039; ) then&lt;br /&gt;
			v = trim( v )&lt;br /&gt;
			local title = v:match( &amp;#039;^|%[%[(.-)|&amp;#039; )&lt;br /&gt;
			local rawDataList = v:match( &amp;#039;^|.-|.-|(.*)&amp;#039; ) -- This is everything after the title&lt;br /&gt;
&lt;br /&gt;
			if not usesInclude then&lt;br /&gt;
				if title and title ~= &amp;#039;&amp;#039; then&lt;br /&gt;
					table.insert( res, title )&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				-- When multiple includes are used (e.g. include={Template1},{Template2} or include={Template}:1:2) their results are separated by a pipe&lt;br /&gt;
				rawDataList = split( rawDataList, &amp;#039;|&amp;#039;, true )&lt;br /&gt;
				local cleanedDataList = {}&lt;br /&gt;
&lt;br /&gt;
				for _incIndex, dataItem in ipairs( rawDataList ) do&lt;br /&gt;
					local incIndex = ((_incIndex - 1) % #includedParamNames) + 1 -- Needed in case the same template appears multiple times on the same page&lt;br /&gt;
					dataItem = unEscape( dataItem )&lt;br /&gt;
					dataItem = trim( dataItem )&lt;br /&gt;
&lt;br /&gt;
					if includedParamNames[ incIndex ].isTemplate and includedParamNames[ incIndex ].includeAll then -- Check if we included a full template&lt;br /&gt;
						-- When we include an entire template we use the %ARGS% parameter supplied by dpl.&lt;br /&gt;
						-- However all | characters are repaced with §, e.g.:&lt;br /&gt;
						-- §namelessParam&lt;br /&gt;
						-- §param = text [[wowee§link text]]&lt;br /&gt;
						-- §param2 = text {{something§something else}}&lt;br /&gt;
						dataItem = dataItem:gsub( &amp;#039;\127\&amp;#039;&amp;quot;`UNIQ%-%-nowiki%-%x+%-QINU`&amp;quot;\&amp;#039;\127&amp;#039;, function(item) return &amp;#039;&amp;lt;nowiki&amp;gt;&amp;#039; .. item .. &amp;#039;&amp;lt;/nowiki&amp;gt;&amp;#039; end )&lt;br /&gt;
						dataItem = mw.text.unstripNoWiki( dataItem ) -- Unstrip nowiki so we can clean their content&lt;br /&gt;
						dataItem = fixCurlyBrackets( dataItem ) -- When using the %ARGS% dpl parameter, curly brackets are replaced with ❴ (U+2774) and ❵ (U+2775)&lt;br /&gt;
						dataItem = dataItem:gsub( &amp;#039;%b{}&amp;#039;, function(x) return x:gsub( &amp;#039;§&amp;#039;, &amp;#039;|&amp;#039; ) end ) -- Restore pipe characters inside links and templates&lt;br /&gt;
						dataItem = dataItem:gsub( &amp;#039;%b[]&amp;#039;, function(x) return x:gsub( &amp;#039;§&amp;#039;, &amp;#039;|&amp;#039; ) end )&lt;br /&gt;
						dataItem = dataItem:gsub( &amp;#039;&amp;lt;nowiki&amp;gt;(.-)&amp;lt;/nowiki&amp;gt;&amp;#039;, function(x) return mw.getCurrentFrame():extensionTag( &amp;#039;nowiki&amp;#039;, x ) end ) -- Restrip nowiki&lt;br /&gt;
						local _dataItem = {}&lt;br /&gt;
&lt;br /&gt;
						if dataItem ~= &amp;#039;&amp;#039; then&lt;br /&gt;
							dataItem = split( dataItem:sub( 3 ), &amp;#039;§&amp;#039; ) -- The sub(3) removes the first § at the start. § is 2 bytes wide so start at index 3&lt;br /&gt;
&lt;br /&gt;
							for i, item in ipairs( dataItem ) do&lt;br /&gt;
								if item:find( &amp;#039;=&amp;#039; ) then -- Check if the parameter is named or unnamed&lt;br /&gt;
									local param, value = item:match( &amp;#039;^%s*(.-)%s*=%s*(.-)%s*$&amp;#039; )&lt;br /&gt;
									_dataItem[ param ] = value&lt;br /&gt;
								else&lt;br /&gt;
									table.insert( _dataItem, trim( item ) )&lt;br /&gt;
								end&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
&lt;br /&gt;
						dataItem = _dataItem&lt;br /&gt;
					end&lt;br /&gt;
&lt;br /&gt;
					local dataListIndex = groupMultiTemplateResults and 1 or math.ceil( _incIndex / #includedParamNames )&lt;br /&gt;
					if&lt;br /&gt;
						includedParamNames[ incIndex ].isTemplate and&lt;br /&gt;
						not includedParamNames[ incIndex ].includeAll and&lt;br /&gt;
						not includedParamNames[ incIndex ].hasPhantomTemplate&lt;br /&gt;
					then -- This means there was an include in the form &amp;#039;include = {template}:param&amp;#039;&lt;br /&gt;
						local templateName = includedParamNames[ incIndex ].name&lt;br /&gt;
						local paramName = includedParamNames[ incIndex ].param&lt;br /&gt;
						paramName = tonumber( paramName ) or paramName -- Keep as string if tonumber fails&lt;br /&gt;
						cleanedDataList[ dataListIndex ] = cleanedDataList[ dataListIndex ] or {}&lt;br /&gt;
						cleanedDataList[ dataListIndex ][ templateName ] = cleanedDataList[ dataListIndex ][ templateName ] or {}&lt;br /&gt;
						&lt;br /&gt;
						if groupMultiTemplateResults and _incIndex &amp;gt; #includedParamNames then&lt;br /&gt;
							mergeItem( cleanedDataList[ dataListIndex ][ templateName ], paramName, dataItem )&lt;br /&gt;
						else&lt;br /&gt;
							cleanedDataList[ dataListIndex ][ templateName ][ paramName ] = dataItem&lt;br /&gt;
						end&lt;br /&gt;
					else&lt;br /&gt;
						local templateName = includedParamNames[ incIndex ].name&lt;br /&gt;
						cleanedDataList[ dataListIndex ] = cleanedDataList[ dataListIndex ] or {}&lt;br /&gt;
						&lt;br /&gt;
						if groupMultiTemplateResults and _incIndex &amp;gt; #includedParamNames then&lt;br /&gt;
							mergeItem( cleanedDataList[ dataListIndex ], templateName, dataItem )&lt;br /&gt;
						else&lt;br /&gt;
							cleanedDataList[ dataListIndex ][ templateName ] = dataItem&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				if title and title ~= &amp;#039;&amp;#039; then&lt;br /&gt;
					for _, v in ipairs( cleanedDataList ) do&lt;br /&gt;
						table.insert( res, { title=title, include=v } )&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;
	return res&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Accepts a series of tables each containig the settings for a dpl query.&lt;br /&gt;
-- Combinig multiple dpl queries yields better performance than doing them sequentially&lt;br /&gt;
function dpl.ask( ... )&lt;br /&gt;
	local formatTime = os.clock()&lt;br /&gt;
	local queries = { ... }&lt;br /&gt;
	local wantsGrouping = {}&lt;br /&gt;
&lt;br /&gt;
	for i = 1, #queries do&lt;br /&gt;
		checkType( &amp;#039;Module:DPLlua.ask&amp;#039;, i, queries[i], &amp;#039;table&amp;#039; )&lt;br /&gt;
		table.insert( wantsGrouping, queries[i].groupMultiTemplateResults or false )&lt;br /&gt;
		removeFormattingSettings( queries[i] )&lt;br /&gt;
		queries[i] = formatDpl( queries[i] )&lt;br /&gt;
	end&lt;br /&gt;
	formatTime = os.clock() - formatTime&lt;br /&gt;
&lt;br /&gt;
	local DPLtime = os.clock()&lt;br /&gt;
	queries = table.concat( queries, &amp;#039;$@µ@$&amp;#039; )&lt;br /&gt;
	queries = mw.getCurrentFrame():preprocess( queries )&lt;br /&gt;
	queries = split( queries, &amp;#039;$@µ@$&amp;#039;, true )&lt;br /&gt;
	DPLtime = os.clock() - DPLtime&lt;br /&gt;
&lt;br /&gt;
	for i = 1, #queries do&lt;br /&gt;
		local parseTime = os.clock()&lt;br /&gt;
		queries[i] = toTable( queries[i], wantsGrouping[i] )&lt;br /&gt;
		parseTime = os.clock() - parseTime&lt;br /&gt;
		queries[i][&amp;#039;DPL time&amp;#039;] = DPLtime&lt;br /&gt;
		queries[i][&amp;#039;Parse time&amp;#039;] = math.floor( (formatTime + parseTime) * 1e5 ) / 1e5 -- os.clock() has a resolution of 10µs&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return unpack( queries )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- function dpl.test()&lt;br /&gt;
-- 	local time = os.clock()&lt;br /&gt;
&lt;br /&gt;
	-- local a, b = dpl.ask({&lt;br /&gt;
	--     namespace = &amp;#039;Module&amp;#039;,&lt;br /&gt;
	--     linksto = &amp;#039;Module:Chart data&amp;#039;,&lt;br /&gt;
	--     distinct = &amp;#039;strict&amp;#039;,&lt;br /&gt;
	--     ordermethod = &amp;#039;title&amp;#039;,&lt;br /&gt;
	--     nottitlematch = &amp;#039;%/doc¦%sandbox%¦Exchange/%¦Exchange historical/%¦Chart data&amp;#039;,&lt;br /&gt;
	-- 	ignorecase = &amp;#039;true&amp;#039;,&lt;br /&gt;
	-- 	allowcachedresults = false&lt;br /&gt;
	-- },{&lt;br /&gt;
	--     namespace = &amp;#039;Module&amp;#039;,&lt;br /&gt;
	--     linksto = &amp;#039;Module:Enum&amp;#039;,&lt;br /&gt;
	--     distinct = &amp;#039;strict&amp;#039;,&lt;br /&gt;
	--     ordermethod = &amp;#039;title&amp;#039;,&lt;br /&gt;
	-- 	nottitlematch = &amp;#039;%/doc¦%sandbox%¦Exchange/%¦Exchange historical/%¦Enum&amp;#039;,&lt;br /&gt;
	--     ignorecase = &amp;#039;true&amp;#039;,&lt;br /&gt;
	-- 	allowcachedresults = false&lt;br /&gt;
	-- })&lt;br /&gt;
	-- mw.logObject(a)&lt;br /&gt;
	-- mw.logObject(b)&lt;br /&gt;
&lt;br /&gt;
	-- local a, b = dpl.ask({&lt;br /&gt;
	--     namespace = &amp;#039;Module&amp;#039;,&lt;br /&gt;
	--     linksto = &amp;#039;Module:Chart data&amp;#039;,&lt;br /&gt;
	--     distinct = &amp;#039;strict&amp;#039;,&lt;br /&gt;
	--     ordermethod = &amp;#039;title&amp;#039;,&lt;br /&gt;
	--     nottitlematch = &amp;#039;%/doc¦%sandbox%¦Exchange/%¦Exchange historical/%¦Chart data&amp;#039;,&lt;br /&gt;
	--     ignorecase = &amp;#039;true&amp;#039;,&lt;br /&gt;
	-- 	allowcachedresults = false&lt;br /&gt;
	-- },{&lt;br /&gt;
	-- 	namespace = &amp;#039;&amp;#039;,&lt;br /&gt;
	-- 	ignorecase = &amp;#039;true&amp;#039;,&lt;br /&gt;
	-- 	uses = &amp;#039;Template:Infobox Recipe&amp;#039;,&lt;br /&gt;
	-- 	count = 50,&lt;br /&gt;
	-- 	include = &amp;#039;{Infobox Recipe},{Infobox Item}&amp;#039;,&lt;br /&gt;
	-- 	allowcachedresults = false&lt;br /&gt;
	-- })&lt;br /&gt;
	-- mw.logObject(a)&lt;br /&gt;
	-- mw.logObject(b)&lt;br /&gt;
&lt;br /&gt;
	-- local a = dpl.ask{&lt;br /&gt;
	-- 	namespace = &amp;#039;&amp;#039;,&lt;br /&gt;
	-- 	uses = &amp;#039;Template:Infobox Recipe&amp;#039;,&lt;br /&gt;
	-- 	include = &amp;#039;{Infobox Recipe}:skill:name,{Infobox Item}:update,{Infobox Item|test}&amp;#039;,&lt;br /&gt;
	-- 	count = 50,&lt;br /&gt;
	-- 	ordermethod = &amp;#039;title&amp;#039;,&lt;br /&gt;
	-- }&lt;br /&gt;
	-- mw.logObject(a)&lt;br /&gt;
&lt;br /&gt;
	-- local q = dpl.ask{&lt;br /&gt;
	-- 	uses = &amp;quot;Template:Collections table&amp;quot;,&lt;br /&gt;
	-- 	category = &amp;quot;Archaeology collections&amp;quot;,&lt;br /&gt;
	-- 	-- include = &amp;quot;{Infobox collection}:reward,{Collections table}:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15&amp;quot;,&lt;br /&gt;
	-- 	include = &amp;quot;{Infobox collection}:reward,{Collections table}&amp;quot;,&lt;br /&gt;
	-- 	count = 100&lt;br /&gt;
	-- }&lt;br /&gt;
	-- mw.logObject(q)&lt;br /&gt;
	&lt;br /&gt;
	-- local q = dpl.ask{&lt;br /&gt;
	-- 	namespace = &amp;quot;&amp;quot;,&lt;br /&gt;
	-- 	uses = &amp;quot;Template:Infobox spell&amp;quot;,&lt;br /&gt;
	-- 	notcategory = {&amp;quot;Removed content&amp;quot;, &amp;quot;Removed spells&amp;quot;},&lt;br /&gt;
	-- 	nottitlematch = {&amp;quot;Enchant Crossbow Bolt&amp;quot;, &amp;quot;Storm of Armadyl&amp;quot;},&lt;br /&gt;
	-- 	include = &amp;quot;{Infobox spell}&amp;quot;,&lt;br /&gt;
	-- }&lt;br /&gt;
	-- mw.logObject(q)&lt;br /&gt;
&lt;br /&gt;
-- 	local list = dpl.ask{&lt;br /&gt;
-- 		namespace = &amp;#039;Template&amp;#039;,&lt;br /&gt;
-- 		uses = &amp;#039;Template:Navbox&amp;#039;,&lt;br /&gt;
-- 		ordermethod = &amp;#039;title&amp;#039;,&lt;br /&gt;
-- 		include = &amp;#039;{Navbox}:gtitle1:gtitle2&amp;#039;,&lt;br /&gt;
-- 		count = 1,&lt;br /&gt;
-- 		offset = 3&lt;br /&gt;
-- 	}&lt;br /&gt;
-- 	mw.logObject(list)&lt;br /&gt;
&lt;br /&gt;
-- 	local list = dpl.ask{&lt;br /&gt;
-- 		namespace = &amp;#039;User&amp;#039;,&lt;br /&gt;
-- 		titlematch = &amp;#039;CephHunter/Sandbox/test1&amp;#039;,&lt;br /&gt;
-- 		include = &amp;#039;{User:CephHunter/Sandbox/test2|User:CephHunter/Sandbox/test3},{User:CephHunter/Sandbox/test3}:1&amp;#039;,&lt;br /&gt;
-- 	}&lt;br /&gt;
-- 	mw.logObject(list)&lt;br /&gt;
&lt;br /&gt;
-- 	mw.logObject(dpl.ask{&lt;br /&gt;
-- 		namespace = &amp;#039;User&amp;#039;,&lt;br /&gt;
-- 		ignorecase = &amp;#039;true&amp;#039;,&lt;br /&gt;
-- 		titlematch = &amp;#039;CephHunter/Sandbox/test1&amp;#039;,&lt;br /&gt;
-- 		include = &amp;#039;{User:CephHunter/Sandbox/test2}&amp;#039;&lt;br /&gt;
-- 	})&lt;br /&gt;
&lt;br /&gt;
-- 	mw.logObject(dpl.ask{&lt;br /&gt;
-- 		namespace = &amp;#039;Module&amp;#039;,&lt;br /&gt;
-- 		uses = &amp;#039;Template:Helper module&amp;#039;,&lt;br /&gt;
-- 		titlematch = &amp;#039;%/doc&amp;#039;,&lt;br /&gt;
-- 		nottitlematch = &amp;#039;Exchange/%|Exchange historical/%|Sandbox/%&amp;#039;,&lt;br /&gt;
-- 		ordermethod = &amp;#039;title&amp;#039;,&lt;br /&gt;
-- 		include = &amp;#039;{Helper module}, {Helper module}:example&amp;#039;,&lt;br /&gt;
-- 		count = 1,&lt;br /&gt;
-- 		offset = 13&lt;br /&gt;
-- 	})&lt;br /&gt;
&lt;br /&gt;
-- 	mw.logObject(dpl.ask{&lt;br /&gt;
--         namespace = &amp;#039;Module&amp;#039;,&lt;br /&gt;
--         titlematch = &amp;#039;Chart data|Absorbative calculator&amp;#039;,&lt;br /&gt;
--         nottitlematch = &amp;#039;Exchange/%|Exchange historical/%|Sandbox/%|%/doc|DPLlua%&amp;#039;,&lt;br /&gt;
--         ordermethod = &amp;#039;title&amp;#039;,&lt;br /&gt;
--         include = &amp;#039;%0&amp;#039;&lt;br /&gt;
-- 	})&lt;br /&gt;
&lt;br /&gt;
-- 	mw.logObject(dpl.ask{&lt;br /&gt;
--         uses = &amp;#039;Template:Collections table&amp;#039;,&lt;br /&gt;
--         include = &amp;#039;{Collections table}&amp;#039;,&lt;br /&gt;
--         count = 5&lt;br /&gt;
-- 	})&lt;br /&gt;
&lt;br /&gt;
-- 	mw.log(os.clock()-time)&lt;br /&gt;
-- end&lt;br /&gt;
&lt;br /&gt;
return dpl&lt;br /&gt;
-- &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zeroclanzhang</name></author>
	</entry>
</feed>