<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://calimasaga.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3ASubject_index</id>
	<title>Module:Subject index - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://calimasaga.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3ASubject_index"/>
	<link rel="alternate" type="text/html" href="https://calimasaga.com/w/index.php?title=Module:Subject_index&amp;action=history"/>
	<updated>2026-11-09T05:11:57Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://calimasaga.com/w/index.php?title=Module:Subject_index&amp;diff=1746&amp;oldid=prev</id>
		<title>WikiAdmin: World pages as dictionaries grouped by letter</title>
		<link rel="alternate" type="text/html" href="https://calimasaga.com/w/index.php?title=Module:Subject_index&amp;diff=1746&amp;oldid=prev"/>
		<updated>2026-10-29T05:09:00Z</updated>

		<summary type="html">&lt;p&gt;World pages as dictionaries grouped by letter&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Module:Subject index&lt;br /&gt;
-- Every subject of one kind (from the Cargo table Subjects, filled by&lt;br /&gt;
-- {{Appears in}}), as a dictionary grouped under the initial letter of its&lt;br /&gt;
-- name in the page&amp;#039;s language. A leading article is ignored for sorting and&lt;br /&gt;
-- grouping, so &amp;quot;The Old Warrior&amp;quot; files under O and &amp;quot;La Cábala&amp;quot; under C.&lt;br /&gt;
--&lt;br /&gt;
--   {{#invoke:Subject index|main|kind=faction|lang=es}}&lt;br /&gt;
--   kind: character, faction, place, belief or force&lt;br /&gt;
--   lang: es or ca for a translation; empty for English&lt;br /&gt;
--   work: optional, only subjects appearing in that work&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local ARTICLES = {&lt;br /&gt;
	en = { &amp;#039;The &amp;#039; },&lt;br /&gt;
	es = { &amp;#039;El &amp;#039;, &amp;#039;La &amp;#039;, &amp;#039;Los &amp;#039;, &amp;#039;Las &amp;#039; },&lt;br /&gt;
	ca = { &amp;#039;El &amp;#039;, &amp;#039;La &amp;#039;, &amp;#039;Els &amp;#039;, &amp;#039;Les &amp;#039;, &amp;quot;L&amp;#039;&amp;quot;, &amp;#039;En &amp;#039;, &amp;#039;Na &amp;#039; },&lt;br /&gt;
}&lt;br /&gt;
local PLAIN = {&lt;br /&gt;
	[&amp;#039;Á&amp;#039;] = &amp;#039;A&amp;#039;, [&amp;#039;À&amp;#039;] = &amp;#039;A&amp;#039;, [&amp;#039;É&amp;#039;] = &amp;#039;E&amp;#039;, [&amp;#039;È&amp;#039;] = &amp;#039;E&amp;#039;, [&amp;#039;Í&amp;#039;] = &amp;#039;I&amp;#039;, [&amp;#039;Ï&amp;#039;] = &amp;#039;I&amp;#039;,&lt;br /&gt;
	[&amp;#039;Ó&amp;#039;] = &amp;#039;O&amp;#039;, [&amp;#039;Ò&amp;#039;] = &amp;#039;O&amp;#039;, [&amp;#039;Ú&amp;#039;] = &amp;#039;U&amp;#039;, [&amp;#039;Ü&amp;#039;] = &amp;#039;U&amp;#039;, [&amp;#039;Ç&amp;#039;] = &amp;#039;C&amp;#039;, [&amp;#039;Ñ&amp;#039;] = &amp;#039;N&amp;#039;,&lt;br /&gt;
	[&amp;#039;á&amp;#039;] = &amp;#039;a&amp;#039;, [&amp;#039;à&amp;#039;] = &amp;#039;a&amp;#039;, [&amp;#039;é&amp;#039;] = &amp;#039;e&amp;#039;, [&amp;#039;è&amp;#039;] = &amp;#039;e&amp;#039;, [&amp;#039;í&amp;#039;] = &amp;#039;i&amp;#039;, [&amp;#039;ï&amp;#039;] = &amp;#039;i&amp;#039;,&lt;br /&gt;
	[&amp;#039;ó&amp;#039;] = &amp;#039;o&amp;#039;, [&amp;#039;ò&amp;#039;] = &amp;#039;o&amp;#039;, [&amp;#039;ú&amp;#039;] = &amp;#039;u&amp;#039;, [&amp;#039;ü&amp;#039;] = &amp;#039;u&amp;#039;, [&amp;#039;ç&amp;#039;] = &amp;#039;c&amp;#039;, [&amp;#039;ñ&amp;#039;] = &amp;#039;n&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
local NONE = { en = &amp;quot;&amp;#039;&amp;#039;None yet.&amp;#039;&amp;#039;&amp;quot;, es = &amp;quot;&amp;#039;&amp;#039;Ninguno todavía.&amp;#039;&amp;#039;&amp;quot;, ca = &amp;quot;&amp;#039;&amp;#039;Encara cap.&amp;#039;&amp;#039;&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
local function plain(s)&lt;br /&gt;
	return (mw.ustring.gsub(s, &amp;#039;.&amp;#039;, PLAIN))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- The name without its leading article: what the dictionary sorts on.&lt;br /&gt;
local function sortName(name, lang)&lt;br /&gt;
	for _, article in ipairs(ARTICLES[lang] or ARTICLES.en) do&lt;br /&gt;
		local n = mw.ustring.len(article)&lt;br /&gt;
		if mw.ustring.sub(name, 1, n) == article and mw.ustring.len(name) &amp;gt; n then&lt;br /&gt;
			return mw.ustring.sub(name, n + 1)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local kind = mw.text.trim(args.kind or &amp;#039;&amp;#039;)&lt;br /&gt;
	local lang = mw.text.trim(args.lang or &amp;#039;&amp;#039;)&lt;br /&gt;
	if lang == &amp;#039;&amp;#039; then&lt;br /&gt;
		lang = &amp;#039;en&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	local where = &amp;quot;kind=&amp;#039;&amp;quot; .. kind:gsub(&amp;quot;&amp;#039;&amp;quot;, &amp;#039;&amp;#039;) .. &amp;quot;&amp;#039;&amp;quot;&lt;br /&gt;
	local work = mw.text.trim(args.work or &amp;#039;&amp;#039;)&lt;br /&gt;
	if work ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		where = where .. &amp;quot; AND works HOLDS &amp;#039;&amp;quot; .. work:gsub(&amp;quot;&amp;#039;&amp;quot;, &amp;#039;&amp;#039;) .. &amp;quot;&amp;#039;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local rows = mw.ext.cargo.query(&amp;#039;Subjects&amp;#039;, &amp;#039;_pageName=page,name_es=name_es,name_ca=name_ca&amp;#039;,&lt;br /&gt;
		{ where = where, limit = 5000 })&lt;br /&gt;
&lt;br /&gt;
	local items = {}&lt;br /&gt;
	for _, row in ipairs(rows) do&lt;br /&gt;
		local name = row.page&lt;br /&gt;
		local target = row.page&lt;br /&gt;
		if lang ~= &amp;#039;en&amp;#039; then&lt;br /&gt;
			local translated = row[&amp;#039;name_&amp;#039; .. lang]&lt;br /&gt;
			if translated and translated ~= &amp;#039;&amp;#039; then&lt;br /&gt;
				name = translated&lt;br /&gt;
			end&lt;br /&gt;
			local t = mw.title.new(row.page .. &amp;#039;/&amp;#039; .. lang)&lt;br /&gt;
			if t and t.exists then&lt;br /&gt;
				target = row.page .. &amp;#039;/&amp;#039; .. lang&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local key = plain(sortName(name, lang))&lt;br /&gt;
		local letter = mw.ustring.upper(mw.ustring.sub(key, 1, 1))&lt;br /&gt;
		if not letter:match(&amp;#039;^%u$&amp;#039;) then&lt;br /&gt;
			letter = &amp;#039;#&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(items, { name = name, target = target, key = mw.ustring.lower(key), letter = letter })&lt;br /&gt;
	end&lt;br /&gt;
	if #items == 0 then&lt;br /&gt;
		return NONE[lang] or NONE.en&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(items, function(a, b)&lt;br /&gt;
		return a.key &amp;lt; b.key&lt;br /&gt;
	end)&lt;br /&gt;
&lt;br /&gt;
	local groups, letters = {}, {}&lt;br /&gt;
	for _, item in ipairs(items) do&lt;br /&gt;
		if not groups[item.letter] then&lt;br /&gt;
			groups[item.letter] = {}&lt;br /&gt;
			table.insert(letters, item.letter)&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(groups[item.letter], item)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local anchor = function(letter)&lt;br /&gt;
		return &amp;#039;letter-&amp;#039; .. (letter == &amp;#039;#&amp;#039; and &amp;#039;other&amp;#039; or letter)&lt;br /&gt;
	end&lt;br /&gt;
	local out, bar = {}, {}&lt;br /&gt;
	for _, letter in ipairs(letters) do&lt;br /&gt;
		table.insert(bar, &amp;#039;[[#&amp;#039; .. anchor(letter) .. &amp;#039;|&amp;#039; .. letter .. &amp;#039;]]&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(out, &amp;#039;&amp;lt;div class=&amp;quot;calima-letters&amp;quot;&amp;gt;&amp;#039; .. table.concat(bar, &amp;#039; &amp;#039;) .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
	table.insert(out, &amp;#039;&amp;lt;div class=&amp;quot;calima-dict&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
	for _, letter in ipairs(letters) do&lt;br /&gt;
		table.insert(out, &amp;#039;&amp;lt;div class=&amp;quot;calima-dict__group&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
		table.insert(out, &amp;#039;&amp;lt;div class=&amp;quot;calima-dict__letter&amp;quot; id=&amp;quot;&amp;#039; .. anchor(letter) .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; .. letter .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
		for _, item in ipairs(groups[letter]) do&lt;br /&gt;
			table.insert(out, &amp;#039;&amp;lt;div class=&amp;quot;calima-dict__item&amp;quot;&amp;gt;[[&amp;#039; .. item.target .. &amp;#039;|&amp;#039; .. item.name .. &amp;#039;]]&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
	return table.concat(out, &amp;#039;\n&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>WikiAdmin</name></author>
	</entry>
</feed>