Jump to content

Module:also

From Wiktionary, the free dictionary

This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

local export = {}

local debug_track_module = "Module:debug/track"
local headword_data_module = "Module:headword/data"
local links_module = "Module:links"
local script_utilities_module = "Module:script utilities"
local scripts_module = "Module:scripts"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local unicode_data_module = "Module:Unicode data"

local insert = table.insert
local ipairs = ipairs
local require = require
local type = type

--[==[
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.]==]
	local function codepoint(...)
		codepoint = require(string_utilities_module).codepoint
		return codepoint(...)
	end
	
	local function find_best_script_without_lang(...)
		find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang
		return find_best_script_without_lang(...)
	end

	local function lookup_name(...)
		lookup_name = require(unicode_data_module).lookup_name
		return lookup_name(...)
	end

	local function plain_link(...)
		plain_link = require(links_module).plain_link
		return plain_link(...)
	end

	local function serial_comma_join(...)
		serial_comma_join = require(table_module).serialCommaJoin
		return serial_comma_join(...)
	end

	local function tag_text(...)
		tag_text = require(script_utilities_module).tag_text
		return tag_text(...)
	end

	local function track(...)
		track = require(debug_track_module)
		return track(...)
	end

--[==[
Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as "foo or get_foo()", where the function get_foo sets the object to "foo" 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 "foo" has been set, "get_foo" will not be called again.]==]
	local pagename
	local function get_pagename()
		pagename, get_pagename = mw.loadData(headword_data_module).pagename, nil
		return pagename
	end

function export.main(terms)
	local items, use_semicolon = {}, false
	for _, v in ipairs(terms) do
		local term = type(v) == "string" and v or v.term
		-- Don't add the link if it's the current pagename.
		if term ~= (pagename or get_pagename()) then
			local uni = v.uni
			if uni == nil then -- Use uni_default iff uni is not specified at all.
				uni = terms.uni_default
			end
			
			if not use_semicolon and term:find(",") then
				use_semicolon = true
			end
			
			-- Get the script if not already given.
			local sc = v.sc or find_best_script_without_lang(term)
			-- Create the link.
			local link = tag_text(plain_link{term = term, sc = sc}, nil, sc, "bold")
			
			local cp
			if uni then
				track("also/uni")
				if uni == "auto" then
					cp = term:match("^.[\128-\191]*$") and codepoint(term) or nil
				else
					cp = tonumber(uni)
					track(("also/uni/%s"):format(
						term:match("^.[\128-\191]*$") and cp == codepoint(term) and "auto" or "noauto"
					))
				end
			end
			
			if cp then
				link = link .. (" <small>[U+%04X %s]</small>"):format(
					cp,
					lookup_name(cp):gsub("<", "&lt;"):gsub(">", "&gt;")
				)
			end
			
			insert(items, link)
		end
	end
	
	if #items == 0 then
		error("Please specify at least one term which is not the current page title.")
	end
	
	return ("<div class=\"disambig-see-also\">''See also:'' %s</div>"):format(serial_comma_join(items, {
		conj = "''and''",
		punc = use_semicolon and ";" or ","
	}))
end

return export