Module:also: Difference between revisions

From Linguifex
Jump to navigation Jump to search
Created page with "local export = {} local yesno = require('Module:yesno') local get_script -- If there are characters in both scripts (the key and value), the second -- should be used. local..."
 
m 1 revision imported
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
local export = {}
local export = {}


local yesno = require('Module:yesno')
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 get_script
local insert = table.insert
local ipairs = ipairs
local require = require
local type = type


-- If there are characters in both scripts (the key and value), the second
--[==[
-- should be used.
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 overridden_by = {
local function codepoint(...)
Latn = "Latinx",
codepoint = require(string_utilities_module).codepoint
Grek = "polytonic",
return codepoint(...)
Cyrl = "Cyrs",
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


-- Join with serial "and" and serial comma
local function serial_comma_join(...)
local function serial_comma_join(seq, conjunction)
serial_comma_join = require(table_module).serialCommaJoin
conjunction = conjunction or ","
return serial_comma_join(...)
if #seq == 0 then
return ""
elseif #seq == 1 then
return seq[1] -- nothing to join
elseif #seq == 2 then
return seq[1] .. " ''and'' " .. seq[2]
else
return table.concat(seq, conjunction .. " ", 1, #seq - 1)
.. "<span class='serial-comma'>" .. conjunction .. "</span>" ..
"''<span class='serial-and'> and</span>'' " ..
seq[#seq]
end
end
end


function export.main(frame)
local function tag_text(...)
local args = frame:getParent().args
tag_text = require(script_utilities_module).tag_text
return tag_text(...)
local sc_default = args["sc"]
end
local nosc = yesno(args["nosc"])
 
if nosc then
local function track(...)
if sc_default then
track = require(debug_track_module)
error("|nosc= and |sc= are mutually contradictory. Specify one or the other.")
return track(...)
else
end
-- Turn off script by setting default script to None.
 
sc_default = "None"
--[==[
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
end
 
local uni_default = yesno((args["uni"] == "auto") or args["uni"]) and "auto" or nil
function export.main(terms)
local items, use_semicolon = {}, false
local title = mw.title.getCurrentTitle()
for _, v in ipairs(terms) do
local full_pagename = title.fullText
local term = type(v) == "string" and v or v.term
-- Disables tagging outside of mainspace, where {{also}} more often links to
-- Don't add the link if it's the current pagename.
-- pages that are not entries and don't need tagging. Tagging in Reconstruction
if term ~= (pagename or get_pagename()) then
-- would be more complicated and is often unnecessary, and there are very few
local uni = v.uni
-- entries in Appendix.
if uni == nil then -- Use uni_default iff uni is not specified at all.
local detect_sc = title.nsText == ""
uni = terms.uni_default
or args["detectsc"] -- to test the script detection capabilities
end
local items = {}
local use_semicolon = false
for i, arg in ipairs(args) do
local uni = args["uni" .. i] or uni_default
local sc = args["sc" .. i] or sc_default
if arg:find(",", 1, true) then
use_semicolon = true
end
if not yesno(uni, uni) then
uni = nil
end
local s
local link_text = arg:match("%[%[[^%[%]|]+|(.+)]]") or arg:match("%[%[([^%[%]|]+)]]")
if link_text then
s = arg
arg = mw.text.decode(link_text)
else
s = "[[" .. arg .. "]]"
arg = mw.text.decode(arg)
end
local codepoint
if uni then
if uni == 'auto' then
if not use_semicolon and term:find(",") then
codepoint = (mw.ustring.len(arg) == 1) and mw.ustring.codepoint(arg, 1, 1)
use_semicolon = true
else
codepoint = tonumber(uni)
end
end
end
-- Get the script if not already given.
-- If all characters are in one script, tag the link with it.
local sc = v.sc or find_best_script_without_lang(term)
-- Ignore all "None"-script characters.
-- Create the link.
local rtl
local link = tag_text(plain_link{term = term, sc = sc}, nil, sc, "bold")
if detect_sc and not sc then
-- leading bytes for non-Latin scripts (that is, codepoints between U+340 and U+10FFFF)
local cp
if arg:find("[\200-\244]") then
if uni then
get_script = get_script or require("Module:scripts").charToScript
track("also/uni")
local curr_sc
if uni == "auto" then
for codepoint in mw.ustring.gcodepoint(arg) do
cp = term:match("^.[\128-\191]*$") and codepoint(term) or nil
curr_sc = get_script(codepoint)
else
if curr_sc ~= "None" then
cp = tonumber(uni)
if sc == nil then
track(("also/uni/%s"):format(
sc = curr_sc
term:match("^.[\128-\191]*$") and cp == codepoint(term) and "auto" or "noauto"
elseif curr_sc ~= sc then
))
-- For instance, Grek -> polytonic.
if overridden_by[sc] == curr_sc then
sc = curr_sc
-- For instance, Grek and Latn.
elseif overridden_by[curr_sc] ~= sc then
mw.log("Module:Template:also found two scripts in " .. arg .. ": "
.. sc .. " and " .. curr_sc .. ".")
sc = nil
break
end
end
end
end
end
rtl = mw.loadData("Module:scripts/data")[sc]
rtl = rtl and rtl.direction == "rtl"
else
sc = "Latn"
end
end
end
if cp then
if sc then
link = link .. (" <small>[U+%04X %s]</small>"):format(
s = '<b class="' .. sc .. '">' .. s .. "</b>"
cp,
if rtl then
lookup_name(cp):gsub("<", "&lt;"):gsub(">", "&gt;")
s = s .. "&lrm;"
)
end
end
else
s = "'''" .. s .. "'''"
end
if codepoint then
local m_unidata = require('Module:Unicode data')
s = s .. (" <small>[U+%04X %s]</small>"):format(
insert(items, link)
codepoint,
m_unidata.lookup_name(codepoint):gsub("<", "&lt;")
)
end
if arg ~= full_pagename then
table.insert(items, s)
end
end
end
end
if #items == 0 then
if #items == 0 then
table.insert(items, "{{{1}}}")
error("Please specify at least one term which is not the current page title.")
end
end
return ("<div class=\"disambig-see-also%s\">''See also:'' %s</div>"):format(
return ("<div class=\"disambig-see-also\">''See also:'' %s</div>"):format(serial_comma_join(items, {
(#items == 2) and "-2" or "",
conj = "''and''",
serial_comma_join(items, use_semicolon and ";" or ",")
punc = use_semicolon and ";" or ","
)
}))
end
end


return export
return export

Latest revision as of 11:22, 21 April 2026



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