<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Aget_IDs</id>
	<title>Module:get IDs - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Aget_IDs"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:get_IDs&amp;action=history"/>
	<updated>2026-04-10T21:38:03Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:get_IDs&amp;diff=470890&amp;oldid=prev</id>
		<title>Sware: Created page with &quot;local export = {}  local parameters_module = &quot;Module:parameters&quot; local string_nowiki_module = &quot;Module:string/nowiki&quot; local string_utilities_module = &quot;Module:string utilities&quot; local table_module = &quot;Module:table&quot; local template_parser_module = &quot;Module:template parser&quot;  local anchor_encode = mw.uri.anchorEncode local byte = string.byte local concat = table.concat local format = string.format local get -- Defined below. local gsub = string.gsub local lower = string.lower loc...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:get_IDs&amp;diff=470890&amp;oldid=prev"/>
		<updated>2025-09-16T19:24:56Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local export = {}  local parameters_module = &amp;quot;Module:parameters&amp;quot; local string_nowiki_module = &amp;quot;Module:string/nowiki&amp;quot; local string_utilities_module = &amp;quot;Module:string utilities&amp;quot; local table_module = &amp;quot;Module:table&amp;quot; local template_parser_module = &amp;quot;Module:template parser&amp;quot;  local anchor_encode = mw.uri.anchorEncode local byte = string.byte local concat = table.concat local format = string.format local get -- Defined below. local gsub = string.gsub local lower = string.lower loc...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local export = {}&lt;br /&gt;
&lt;br /&gt;
local parameters_module = &amp;quot;Module:parameters&amp;quot;&lt;br /&gt;
local string_nowiki_module = &amp;quot;Module:string/nowiki&amp;quot;&lt;br /&gt;
local string_utilities_module = &amp;quot;Module:string utilities&amp;quot;&lt;br /&gt;
local table_module = &amp;quot;Module:table&amp;quot;&lt;br /&gt;
local template_parser_module = &amp;quot;Module:template parser&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local anchor_encode = mw.uri.anchorEncode&lt;br /&gt;
local byte = string.byte&lt;br /&gt;
local concat = table.concat&lt;br /&gt;
local format = string.format&lt;br /&gt;
local get -- Defined below.&lt;br /&gt;
local gsub = string.gsub&lt;br /&gt;
local lower = string.lower&lt;br /&gt;
local new_title = mw.title.new&lt;br /&gt;
local normalize_anchor -- Defined below.&lt;br /&gt;
local pcall = pcall&lt;br /&gt;
local require = require&lt;br /&gt;
&lt;br /&gt;
--[==[&lt;br /&gt;
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==]&lt;br /&gt;
	local function class_else_type(...)&lt;br /&gt;
		class_else_type = require(template_parser_module).class_else_type&lt;br /&gt;
		return class_else_type(...)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function decode_entities(...)&lt;br /&gt;
		decode_entities = require(string_utilities_module).decode_entities&lt;br /&gt;
		return decode_entities(...)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function nowiki(...)&lt;br /&gt;
		nowiki = require(string_nowiki_module)&lt;br /&gt;
		return nowiki(...)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function parse(...)&lt;br /&gt;
		parse = require(template_parser_module).parse&lt;br /&gt;
		return parse(...)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function process_params(...)&lt;br /&gt;
		process_params = require(parameters_module).process&lt;br /&gt;
		return process_params(...)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
--[==[&lt;br /&gt;
Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as &amp;quot;foo or get_foo()&amp;quot;, where the function get_foo sets the object to &amp;quot;foo&amp;quot; and then returns it. This ensures they are only loaded when needed, and avoids the need to check for the existence of the object each time, since once &amp;quot;foo&amp;quot; has been set, &amp;quot;get_foo&amp;quot; will not be called again.]==]&lt;br /&gt;
	local parameters_data&lt;br /&gt;
	local function get_parameters_data()&lt;br /&gt;
		parameters_data, get_parameters_data = mw.loadData(&amp;quot;Module:parameters/data&amp;quot;), nil&lt;br /&gt;
		return parameters_data&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local template_names&lt;br /&gt;
	local function get_template_names()&lt;br /&gt;
		template_names = require(table_module).listToSet{&lt;br /&gt;
			&amp;quot;anchor&amp;quot;,&lt;br /&gt;
			&amp;quot;etymid&amp;quot;,&lt;br /&gt;
			&amp;quot;etymon&amp;quot;,&lt;br /&gt;
			&amp;quot;senseid&amp;quot;,&lt;br /&gt;
			&amp;quot;trans-see&amp;quot;,&lt;br /&gt;
			&amp;quot;trans-top&amp;quot;,&lt;br /&gt;
			&amp;quot;trans-top-also&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
		get_template_names = nil&lt;br /&gt;
		return template_names&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
function export.normalize_anchor(str)&lt;br /&gt;
	return decode_entities(anchor_encode(str))&lt;br /&gt;
end&lt;br /&gt;
normalize_anchor = export.normalize_anchor&lt;br /&gt;
&lt;br /&gt;
local function handle_heading(name, seen, ids)&lt;br /&gt;
	-- Repeated IDs are disambiguated by appending _N, where N is an&lt;br /&gt;
	-- incremented integer. When determining this, ASCII characters are case-&lt;br /&gt;
	-- insensitive, but all other characters are case-sensitive.&lt;br /&gt;
	local check = lower(name)&lt;br /&gt;
	if seen[check] then&lt;br /&gt;
		local i, name_lower = 1, check&lt;br /&gt;
		repeat&lt;br /&gt;
			i = i + 1&lt;br /&gt;
			check = format(&amp;quot;%s_%d&amp;quot;, name_lower, i)&lt;br /&gt;
		until not seen[check]&lt;br /&gt;
		name = format(&amp;quot;%s_%d&amp;quot;, name, i)&lt;br /&gt;
	end&lt;br /&gt;
	seen[check] = true&lt;br /&gt;
	ids[#ids + 1] = name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function pseudo_percent_encode(ch)&lt;br /&gt;
	return format(&amp;quot;.%02X&amp;quot;, byte(ch))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function handle_template(name, node, ids)&lt;br /&gt;
	local args, success = node:get_arguments()&lt;br /&gt;
	success, args = pcall(process_params, args, (parameters_data or get_parameters_data())[name])&lt;br /&gt;
	if not success then&lt;br /&gt;
		return&lt;br /&gt;
	elseif name == &amp;quot;anchor&amp;quot; then&lt;br /&gt;
		args = args[1]&lt;br /&gt;
		for i = 1, #args do&lt;br /&gt;
			ids[#ids + 1] = normalize_anchor(args[i])&lt;br /&gt;
		end&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	local id1, id2&lt;br /&gt;
	if name == &amp;quot;trans-top&amp;quot; or name == &amp;quot;trans-see&amp;quot; or name == &amp;quot;trans-top-also&amp;quot; then&lt;br /&gt;
		id1 = &amp;quot;Translations-&amp;quot;&lt;br /&gt;
		if name == &amp;quot;trans-top&amp;quot; then&lt;br /&gt;
			id2 = args.id or args[1]&lt;br /&gt;
		else&lt;br /&gt;
			id2 = args.id.default or args[1]&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		id1 = args[1]:getCanonicalName() .. &amp;quot;: &amp;quot;&lt;br /&gt;
		id2 = args[name == &amp;quot;etymon&amp;quot; and &amp;quot;id&amp;quot; or 2]&lt;br /&gt;
	end&lt;br /&gt;
	if id2 then&lt;br /&gt;
		ids[#ids + 1] = normalize_anchor(id1 .. id2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.get(pagename, force_transclusion)&lt;br /&gt;
	local page, seen, ids = new_title(pagename), {}, {}&lt;br /&gt;
	&lt;br /&gt;
	for node in parse((page.redirectTarget or page):getContent() or error(&amp;quot;Could not retrieve the page content of \&amp;quot;&amp;quot; .. pagename .. &amp;quot;\&amp;quot;.&amp;quot;)):iterate_nodes() do&lt;br /&gt;
		local node_class = class_else_type(node)&lt;br /&gt;
		if node_class == &amp;quot;heading&amp;quot; then&lt;br /&gt;
			local name = node:get_anchor()&lt;br /&gt;
			if name ~= nil then&lt;br /&gt;
				handle_heading(name, seen, ids)&lt;br /&gt;
				-- Headings get a fallback ID, which uses pseudo-percent-encoding&lt;br /&gt;
				-- where &amp;quot;%&amp;quot; is replaced by &amp;quot;.&amp;quot; (e.g. &amp;quot;!&amp;quot; is &amp;quot;.21&amp;quot;).&lt;br /&gt;
				local name2 = gsub(name, &amp;quot;[^%w%-.:_]&amp;quot;, pseudo_percent_encode)&lt;br /&gt;
				if name2 ~= name then&lt;br /&gt;
					handle_heading(name2, seen, ids)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		elseif node_class == &amp;quot;template&amp;quot; then&lt;br /&gt;
			local name = node:get_name(nil, force_transclusion)&lt;br /&gt;
			if (template_names or get_template_names())[name] then&lt;br /&gt;
				handle_template(name, node, ids)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return ids&lt;br /&gt;
end&lt;br /&gt;
get = export.get&lt;br /&gt;
&lt;br /&gt;
-- Used by [[MediaWiki:Gadget-OrangeLinks.js]].&lt;br /&gt;
function export.show(frame)&lt;br /&gt;
	local output = {}&lt;br /&gt;
	&lt;br /&gt;
	for i, pagename in ipairs(frame.args) do&lt;br /&gt;
		output[i] = nowiki(concat(get(pagename, true), &amp;quot; &amp;quot;))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return concat(output, &amp;quot;\n\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
</feed>