Module:User:Catonif/xum2

From Wiktionary, the free dictionary
Jump to navigation Jump to search

This is a private module sandbox of Catonif, for their own experimentation. Items in this module may be added and removed at Catonif's discretion; do not rely on this module's stability.


-- report your complaints at @[[User:Catonif]]

local export = {};

local m_xlit = require('Module:Ital-translit').tr;
local sc_Latn = require("Module:scripts").getByCode("Latn");
local format_quote = require("Module:usex").format_usex;
local lang_xum = require("Module:languages").getByCode("xum");

local BCE;

local list = {};

local year = {
	['3'] = "late 3<sup>rd</sup>",
	['1'] = "early 2<sup>nd</sup>",
	['5'] = "middle 2<sup>nd</sup>",
	['6'] = "early 1<sup>st</sup>",
};

year['4'] = year['3'];
year['2'] = year['1'];
year['7'] = year['6'];

local roman = {
	["1"] = "I", ["2"] = "II", ["3"] = "III",
	["4"] = "IV", ["5"] = "V", ["6"] = "VI",
	["7"] = "VII",
};

-- reorganises the plain array with blank args as separators given as input into a tree-like structure
local function reorganise(args)

	local tables_i, lines_i, r = 1, 0, {};
	for _, arg in ipairs(args) do
		if (arg == '') then
			lines_i = 0;
			tables_i = tables_i + 1;
		else
			if (lines_i == 0) then
				r[tables_i] = {
					from = arg,
					lines = {},
					-- The following information is redundant to the [from] value but since
					-- it is needed often it's good to calculate it only once.
					table_index = arg:sub(1, 1),
					table_side = arg:sub(2, 2),
				};
			else
				r[tables_i].lines[lines_i] = arg;
			end
			lines_i = lines_i + 1;
		end
	end

	return r;

end

-- deals with linking and bolding for the text of the quote in Umbrian
local function format_text(str, bold)

	local bold_indices = {};

	local word_index = 0;
	str = (str:gsub("<([^<>]+)>", function (word)
		word_index = word_index + 1;
		local match = (word:find("|")) and (word:gsub(".+|", "")) or word;
		if (match == bold) then
			bold_indices[word_index] = true;
			return ("'''[[%s]]'''"):format(word);
		else
			return ("[[%s]]"):format(word);
		end
	end));

	local tr;
	if (str:find("%{")) then
		tr = m_xlit(str
			:gsub("[%[%]%{%}]", "")
			:gsub('_', ' ')
			:gsub('[0-9]+a?', '/')
			:gsub('^/ ', '')
			:gsub('^. ', '')
			:gsub(' .$', ''),
		'xum', 'Ital');
	end

	str = str
		-- { [text in the Italic script] } is used to properly format text in such script
		:gsub("{", "<span class=\"Ital\" lang=\"xum\">"):gsub("}", "</span>")
		-- line numbers are displayed in superscript
		:gsub("([0-9]+a?) ", "<sup>%1</sup>&nbsp;")
		-- . is used for [...], this probably needs to be expanded to fully match [[T:...]]
		:gsub("%.", "[...]")
		-- add a zwsp after colon for proper line breaking
		:gsub("⁚", "⁚&#8203;");

	return str, tr, bold_indices;

end

-- prints a single quote, with the text in Umbrian
-- and optionally with trans-lit and -lation
local function print_line(table, input, pagename)

	local thing, option;

	if (input:match(" ")) then
		thing = (input:gsub(" .+", ""));
		option = (input:gsub(".+ ", ""));
	else
		thing = input;
	end

	local quote = list[table][thing].text;

	local data = { lang = lang_xum, sc = sc_Latn, quote = true }; local bold_indices;

	-- give attested text and translit
	data.usex, data.transliteration, bold_indices = format_text(quote:gsub('_', ''), pagename);

	-- give translation
	if (option == "+" or option == "++") then -- TODO: eventually get rid of <++>
		local t = list[table][thing].t;
		if (t) then
			data.translation = t:gsub("<([^:<>]+):([^:<>]+)>",
				function (word, id)
					if (bold_indices[tonumber(id)]) then
						return ("'''%s'''"):format(word);
					else
						return word;
					end
				end
			);
		end
	else
		data.translation = "-";
	end

	mw.logObject(data);

	mw.log(format_quote(data));

	return format_quote(data);

end

-- interacts with the data in the submodules
local function load_from_submodule(from) -- void
	-- list[from] = require('Module:RQ:xum:TI/' .. from);
	list[from] = require('MOD:User:Catonif/xum2/' .. from);
end

-- puts commas in many different line ranges
local function header_lines(orged)
	r = '';
	for x, v in ipairs(orged.lines) do
		if (v ~= nil) then
			-- reads an attested line and gives the line range
			local s = "";
			for w in list[orged.from][v:gsub(" .+", "")].text:gmatch("%d+[ab]?") do
				s = s .. "-" .. w;
			end
			-- the sub removes the initial hyphence
			r = r .. s:sub(2, -1):gsub("-.+-", "-"):gsub("-", "–") .. ", ";
		end
	end
	-- the sub removes the final comma
	return "lines " .. r:sub(1, -3);
end

-- from a table index, gives the formatted year line in the header
local function header_year(table_index)
	return ("'''%s century %s'''"):format(year[table_index], BCE);
end

-- constant variable, as the title of the work
local header_title = "<cite>[[w:Iguvine Tablets|Iguvine Tablets]]</cite>";

local function header_side(orged)
	return ("table %s, side %s ([https://web.archive.org/web/20221005184445im_/http://www.tavoleeugubine.it/public/image/tavoleeugubine/foto%%20%s%s.jpg photo]; [https://web.archive.org/web/20221005184445if_/http://www.tavoleeugubine.it/public/image/tavoleeugubine/facsimileTI-%s.jpg facsimile]), %s"):format(
		roman[orged.table_index], orged.table_side:upper(),
		roman[orged.table_index], orged.table_side, orged.from,
		header_lines(orged)
	);
end

-- prints a whole side
local function print_side(orged, indent, bold)
	local this_from = orged.from;
	load_from_submodule(this_from);
	local r = header_side(orged) .. ":\n";
	for q, v in ipairs(orged.lines) do
		r = r .. indent .. print_line(this_from, v, bold) .. '\n';
	end
	return r;
end

-- main function
local function side_handler(orged, bold, indent)

	local r = '';

	-- this is the short version, if all the quotes come from a single side
	if (#orged == 1) then
		local table_index = orged[1].table_index;
		r =	indent .. header_year(table_index) .. ", " .. header_title .. ", "
			.. print_side(orged[1], indent .. ":", bold);
	else -- if the quotes come from different sides, then this is the general algorythm
		-- reorganise sides by date of melting
		local in_year = {};
		local years_count = 0; local last_year = "";
		for _, v in ipairs(orged) do
			local here_this_year = year[v.table_index];
			if (here_this_year ~= last_year) then
				years_count = years_count + 1;
				table.insert(in_year, {});
			end
			last_year = here_this_year
			table.insert(in_year[years_count], v);
		end
		-- shorter version, if all sides were melted in the same year
		if (years_count == 1) then
			r = indent .. header_year(in_year[years_count][1].table_index) .. ", " .. header_title .. "\n";
			for _, v in ipairs(in_year[years_count]) do
				r = r .. indent .. ":" .. print_side(v, indent .. "::", bold);
			end
		else -- the general for
			r = indent .. header_title .. "\n";
			for _, v in ipairs(in_year) do
				r = r .. indent .. ":" .. header_year(v[1].table_index) .. ", ";
				for q_, v_ in ipairs(v) do
					if (q_ ~= 1) then r = r .. indent .. ":"; end
					r = r .. print_side(v_, indent .. "::", bold);
				end
			end
		end
	end

	return r;

end

function export.main(frame)

	BCE = frame:expandTemplate { title = "BCE" };

	local args = frame:getParent().args;

	local here_bold = args.bold or mw.title.getCurrentTitle().text;
	local here_indent = args.indent or args.i or '#*';

	return (side_handler(reorganise(args), here_bold, here_indent):gsub("\n$", ""));

end

return export;