A modult a Modul:quick link/doc lapon tudod dokumentálni

local export = {}

local function validate_lang(lang)
	return type(lang) == "table" and type(lang.getCode) == "function"
end

-- Entry names are processed with this function. Catalan has no entry-name
-- replacements, but apparently uses straight apostrophes in entry titles and
-- curly ones in displayed text.
local function curly_apostrophe_to_straight(str)
	return (str:gsub('’', "'"))
end

local function make_tag_func(lang, sc_code)
	if not (validate_lang(lang) and type(sc_code) == "string"
			and mw.loadData "Module:scripts/data"[sc_code]) then
		error("Invalid language object or script code.", 2)
	end
	
	local lang_code, lang_name = lang:getCode(), lang:getCanonicalName()
	
	return function (text)
		return '<span class="' .. sc_code .. '" lang="' .. lang_code .. '">'
			.. text .. '</span>'
	end
end

local function make_link_func(lang)
	if not validate_lang(lang) then
		error("Invalid language object.", 2)
	end
	
	local lang_code, lang_name = lang:getCode(), lang:getCanonicalName()
	
	return function (entry, text)
		return '[[' .. curly_apostrophe_to_straight(entry) .. '#' .. lang_name
			.. '|' .. (text or entry) .. ']]'
	end
end

local function make_link_and_tag_func(lang, sc_code)
	if not (validate_lang(lang) and type(sc_code) == "string"
			and mw.loadData "Module:scripts/data"[sc_code]) then
		error("Invalid language object or script code.", 2)
	end
	
	local lang_code, lang_name = lang:getCode(), lang:getCanonicalName()
	
	return function (entry, text)
		return '<span class="' .. sc_code .. '" lang="' .. lang_code .. '">[['
			.. curly_apostrophe_to_straight(entry) .. '#' .. lang_name .. '|'
			.. (text or entry) .. ']]</span>'
	end
end

-- Find grammatical terms such as "first person" and "plural" in part of the
-- Catalan personal pronouns table and link them.
local function link_terms_in_ca_table(text)
	local ordinals = { 'first', 'second', 'third' }
	
	text = text:gsub(
		'((%d)%l+ %l+)',
		function (whole_match, number)
			return '[[' .. ordinals[tonumber(number)] .. ' person|'
				.. whole_match:gsub(' ', '&nbsp;') .. ']]'
		end)
	
	text = text:gsub(
		'![^\n]+singular.-class="notes%-row"',
		function (table_interior)
			return table_interior:gsub(
				'%l+',
				function (word)
					local link
					if word == 'singular' or word == 'neuter' or word:find 'i[nv]e$'
							or word:find 'al$' then
						link = word
					elseif word == 'majestic' then
						link = 'majestic plural|majestic'
					end
					
					if link then
						return '[[' .. link .. ']]'
					end
				end)
		end)

	return text
end

function export.main(frame)
	local params = {
		title = {},
		lang = {},
		no_make_entry_name = { type = "boolean" },
	}
	
	local args = require "Module:parameters".process(frame.args, params)
	
	local title = args.title
	local lang = require "Module:languages".getByCode(args.lang)
		or require "Module:languages".err(args.lang, "lang")
	
	local content = frame:preprocess("{{" .. title .. "}}")
	
	local link_and_tag, link
	local sc_code = "Latn" -- Fix if language doesn't use Latin script!
	if args.no_make_entry_name or not lang._rawData.entry_name then
		link_and_tag = make_link_and_tag_func(lang, sc_code)
		link = make_link_func(lang)
	else
		local m_links = require "Module:links"
		local full_link = m_links.full_link
		local lang_link = m_links.language_link
		
		link_and_tag = function (entry, text)
			return full_link { term = entry, alt = text,
				lang = lang, sc = require "Module:scripts".getByCode(sc_code),
			}
		end
		
		link = function (entry, text)
			return lang_link { lang = lang, term = entry, alt = text }
		end
	end
	
	local tag = make_tag_func(lang, sc_code)
	
	linked_content = content:gsub(
		"%b[]",
		function (potential_link)
			if potential_link:sub(2, 2) == '[' and potential_link:sub(-2, -2) == ']' then
				local link_contents = potential_link:sub(3, -3) -- strip off outer brackets
				local target, text
				if link_contents:find "|" then
					target, text = link_contents:match "^([^|]+)|(.+)$"
				else
					target = link_contents
				end
				
				if target:find "^([^:]+):" or target:find "#" then
					return "[[" .. link_contents .. "]]"
				 -- There are nested wikilinks; they'd better be matching!
				elseif target:find('[[', 1, true) then
					return tag(target:gsub('%[%[(.-)%]%]', link))
				else
					return link_and_tag(target, text)
				end
			end
		end)
	
	if lang:getCode() == 'ca' then
		linked_content = link_terms_in_ca_table(linked_content)
	end
	
	return linked_content
end

return export