<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ASandbox%2FAseleste%2FIndexer</id>
	<title>Module:Sandbox/Aseleste/Indexer - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ASandbox%2FAseleste%2FIndexer"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Sandbox/Aseleste/Indexer&amp;action=history"/>
	<updated>2026-05-24T16:19:41Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Sandbox/Aseleste/Indexer&amp;diff=145161&amp;oldid=prev</id>
		<title>imported&gt;Aseleste: improve: trim</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Sandbox/Aseleste/Indexer&amp;diff=145161&amp;oldid=prev"/>
		<updated>2021-01-21T02:45:11Z</updated>

		<summary type="html">&lt;p&gt;improve: trim&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Categorizes content and display them.&lt;br /&gt;
-- Improvements are welcomed.&lt;br /&gt;
&lt;br /&gt;
-- requires&lt;br /&gt;
&lt;br /&gt;
-- forward declarations&lt;br /&gt;
local index;&lt;br /&gt;
local process_key_value;&lt;br /&gt;
local build_keys;&lt;br /&gt;
local build_values;&lt;br /&gt;
local as_key_content_function;&lt;br /&gt;
local as_value_content_function;&lt;br /&gt;
local as_fold_function;&lt;br /&gt;
local escape_replacement;&lt;br /&gt;
local unstrip_and_strip_nowiki_tags;&lt;br /&gt;
&lt;br /&gt;
-- exposed: categorizes content and display them&lt;br /&gt;
-- &amp;#039;folder&amp;#039;, &amp;#039;table_*&amp;#039;, &amp;#039;content&amp;#039;&lt;br /&gt;
index = function(frame)&lt;br /&gt;
	local args = build_args(frame)&lt;br /&gt;
	&lt;br /&gt;
	local folder = as_fold_function(args.folder)&lt;br /&gt;
	local keys, key_order = build_keys(args)&lt;br /&gt;
	local values = build_values(args.content)&lt;br /&gt;
	&lt;br /&gt;
	local result = &amp;quot;&amp;quot;&lt;br /&gt;
	-- ordered first&lt;br /&gt;
	for _, categories in ipairs(key_order) do&lt;br /&gt;
		for _, category in ipairs(categories) do&lt;br /&gt;
			local processed = process_key_value(keys, values, category)&lt;br /&gt;
			if processed then&lt;br /&gt;
				result = folder(result, processed)&lt;br /&gt;
				-- remove key and value to mark as processed&lt;br /&gt;
				keys[category] = nil&lt;br /&gt;
				values[category] = nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- unordered last&lt;br /&gt;
	for category, _ in pairs(keys) do&lt;br /&gt;
		local processed = process_key_value(keys, values, category)&lt;br /&gt;
		if processed then&lt;br /&gt;
			result = folder(result, processed)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return frame:getParent():preprocess(result) -- intended to be used with a template&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- process key and value for a given category&lt;br /&gt;
process_key_value = function(keys, values, category)&lt;br /&gt;
	local key = keys[category]&lt;br /&gt;
	if key then&lt;br /&gt;
		local value = values[category]&lt;br /&gt;
		if not value then&lt;br /&gt;
			value = function(category)&lt;br /&gt;
				return &amp;quot;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local result = key(value(category))&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- builds arguments&lt;br /&gt;
-- reads parent frame&lt;br /&gt;
build_args = function(frame)&lt;br /&gt;
	local result = {}&lt;br /&gt;
	&lt;br /&gt;
	for key, value in pairs(frame.args) do&lt;br /&gt;
		result[mw.text.trim(key)] = unstrip_and_strip_nowiki_tags(value)&lt;br /&gt;
	end&lt;br /&gt;
	local pframe = frame:getParent()&lt;br /&gt;
	for key, value in pairs(pframe.args) do&lt;br /&gt;
		result[mw.text.trim(key)] = unstrip_and_strip_nowiki_tags(value)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- builds key mapping, key order mapping&lt;br /&gt;
-- reads &amp;#039;table_*&amp;#039;&lt;br /&gt;
build_keys = function(args)&lt;br /&gt;
	local keys = {}&lt;br /&gt;
	local key_order = {}&lt;br /&gt;
	&lt;br /&gt;
	for arg_k, arg_v in pairs(args) do&lt;br /&gt;
		if arg_k:match(&amp;quot;^table_&amp;quot;) then&lt;br /&gt;
			local key = arg_k:gsub(&amp;quot;table_&amp;quot;, &amp;quot;&amp;quot;, 1)&lt;br /&gt;
			local order = key:match(&amp;quot;^(%d+)_&amp;quot;)&lt;br /&gt;
			if order then&lt;br /&gt;
				key = key:gsub(order .. &amp;quot;_&amp;quot;, &amp;quot;&amp;quot;, 1)&lt;br /&gt;
				local order_list = key_order[order]&lt;br /&gt;
				if order_list then&lt;br /&gt;
					table.insert(order_list, key)&lt;br /&gt;
				else&lt;br /&gt;
					key_order[order] = {key}&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			keys[key] = as_key_content_function(arg_v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- sort key order&lt;br /&gt;
	local key_order_list = {}&lt;br /&gt;
	for order, category in pairs(key_order) do&lt;br /&gt;
		table.insert(key_order_list, {key=tonumber(order), value=category})&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(key_order_list, function(a, b) return a.key &amp;lt; b.key end)&lt;br /&gt;
	key_order = {}&lt;br /&gt;
	for _, value in ipairs(key_order_list) do&lt;br /&gt;
		table.insert(key_order, value.value)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return keys, key_order&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- builds values mapping&lt;br /&gt;
-- magic words: &amp;#039;__M_INDEX__&amp;#039;&lt;br /&gt;
-- syntax: &amp;#039;__M_INDEX__ [category1] [category2] ... [categoryN]&amp;#039;&lt;br /&gt;
build_values = function(text)&lt;br /&gt;
	-- need cleanup&lt;br /&gt;
	local result = {}&lt;br /&gt;
	local context = {}&lt;br /&gt;
	local content = &amp;quot;&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	for _, line in ipairs(mw.text.split(text, &amp;quot;\n&amp;quot;, true)) do -- is \n sufficient&lt;br /&gt;
		if line:match(&amp;quot;^__M_INDEX__&amp;quot;) then&lt;br /&gt;
			-- finish result&lt;br /&gt;
			for _, category in ipairs(context) do&lt;br /&gt;
				local sub_result = result[category]&lt;br /&gt;
				if sub_result == nil then&lt;br /&gt;
 					result[category] = content&lt;br /&gt;
 				else&lt;br /&gt;
 					result[category] = sub_result .. content&lt;br /&gt;
 				end&lt;br /&gt;
			end&lt;br /&gt;
			content = &amp;quot;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- change context&lt;br /&gt;
			context = {}&lt;br /&gt;
			for category in line:gmatch(&amp;quot;%[([^%]]*)%]&amp;quot;) do&lt;br /&gt;
				table.insert(context, category)&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- append content&lt;br /&gt;
			content = content .. line .. &amp;quot;\n&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- one more round of finishing result&lt;br /&gt;
	for _, category in ipairs(context) do&lt;br /&gt;
		local sub_result = result[category]&lt;br /&gt;
		if sub_result == nil then&lt;br /&gt;
 			result[category] = content&lt;br /&gt;
 		else&lt;br /&gt;
 			result[category] = sub_result .. content&lt;br /&gt;
 		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- turn into content function&lt;br /&gt;
	for key, value in pairs(result) do&lt;br /&gt;
		result[key] = as_value_content_function(value)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- converts text to key content function&lt;br /&gt;
-- magic words: &amp;#039;__M_CONTENT__&amp;#039;&lt;br /&gt;
as_key_content_function = function(text)&lt;br /&gt;
	local function func(content)&lt;br /&gt;
		local result = text:gsub(&amp;quot;__M_CONTENT__&amp;quot;, escape_replacement(content)) -- need this variable to only return 1 result&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
	return func&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- converts text to value content function&lt;br /&gt;
-- magic words: &amp;#039;__M_CATEGORY__&amp;#039;&lt;br /&gt;
as_value_content_function = function(text)&lt;br /&gt;
	local function func(category)&lt;br /&gt;
		local result = text:gsub(&amp;quot;__M_CATEGORY__&amp;quot;, escape_replacement(category)) -- need this variable to only return 1 result&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
	return func&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- converts text to folding function&lt;br /&gt;
-- magic words: &amp;#039;__M_LEFT__&amp;#039;, &amp;#039;__M_RIGHT__&amp;#039;&lt;br /&gt;
as_fold_function = function(text)&lt;br /&gt;
	local function func(left, right)&lt;br /&gt;
		-- some improvements could be made here&lt;br /&gt;
		local result = text:gsub(&amp;quot;__M_LEFT__&amp;quot;, escape_replacement(left)):gsub(&amp;quot;__M_RIGHT__&amp;quot;, escape_replacement(right)) -- need this variable to only return 1 result&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
	return func&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- escapes replacement, replace &amp;#039;%&amp;#039; with &amp;#039;%%&amp;#039;&lt;br /&gt;
-- ah, multiple return results cost us headache, apparently multiple return results expand into multiple arguments&lt;br /&gt;
escape_replacement = function(text)&lt;br /&gt;
	local result = text:gsub(&amp;quot;%%&amp;quot;, &amp;quot;%%%%&amp;quot;) -- need this variable to only return 1 result&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
unstrip_and_strip_nowiki_tags = function(text)&lt;br /&gt;
	local result = mw.text.trim(mw.text.unstripNoWiki(text)) -- need this variable to only return 1 result&lt;br /&gt;
			:gsub(&amp;quot;&amp;lt;nowiki&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
			:gsub(&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
			:gsub(&amp;quot;&amp;amp;lt;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;) -- needs to be escaped in the source&lt;br /&gt;
			:gsub(&amp;quot;&amp;amp;gt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;)&lt;br /&gt;
			:gsub(&amp;quot;&amp;amp;quot;&amp;quot;, &amp;#039;&amp;quot;&amp;#039;)&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return {index = index}&lt;/div&gt;</summary>
		<author><name>imported&gt;Aseleste</name></author>
	</entry>
</feed>