Module:Babel

Hello, you have come here looking for the meaning of the word Module:Babel. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:Babel, but we will also tell you about its etymology, its characteristics and you will know how to say Module:Babel in singular and plural. Everything you need to know about the word Module:Babel you have here. The definition of the word Module:Babel will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:Babel, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.

This module implements {{Babel}}, using Module:Babel/data and its subpages to store translated text. Further usage can be found at the documentation page of {{Babel}}.

export.generate_box

function export.generate_box(data)

This is where modules can interface with Babel. data is a table containing the following arguments:

  • obj usually required: Language, script, or family object.
  • lang: Language code. This is required if obj is not passed.
  • code required: Language code affixed with proficiency (or, if unaffixed, proficiency should be native).
  • proficiency required: This can be 0, 1, 2, 3, 4, 5, or N.
  • text required: Text to display in the box.
  • type: Used to determine what formatting to use. This is required if the box being generated is for a script, (non-sign) language, or programming language.
  • glyph: The glyph to show above the script code. This is required for scripts.
  • prog_obj: Programming language data from Module:Babel/data. This is required if the box being generated is for a programming language.
  • translated: Whether text is in English. If this is set to true, the text will be appropriately tagged with Module:script utilities.

export.t_userbox

function export.t_userbox(frame)

Entry point for {{Babel userbox}}.

export.show

function export.show(frame)

Main entry point, for {{Babel}}.


local export = {}

--]
			  and ]
			  to store translated text. Further usage can be found at the
			  documentation page of {{tl|Babel}}. ]==]

local m_data = "Module:Babel/data"
local m_fam = "Module:families"
local m_lang = "Module:languages"
local m_load = "Module:load"
local m_pages = "Module:pages"
local m_para = "Module:parameters"
local m_sc = "Module:scripts"
local m_sc_utils = "Module:script utilities"
local m_str_utils = "Module:string utilities"
local m_track = "Module:debug/track"

local concat = table.concat
local find = string.find
local gmatch = string.gmatch
local gsub = string.gsub
local lower = string.lower
local match = string.match
local next = next
local sub = string.sub
local upper = string.upper

-- Loaders for functions from other modules.

	local function debug_track(...)
		debug_track = require(m_track)
		return debug_track("Babel/" .. ...)
	end
	
	local function fam_get_by_code(...)
		fam_get_by_code = require(m_fam).getByCode
		return fam_get_by_code(...)
	end
	
	local function lang_get_by_code(...)
		lang_get_by_code = require(m_lang).getByCode
		return lang_get_by_code(...)
	end
	
	local function load_data(...)
		load_data = require(m_load).load_data
		return load_data(...)
	end
	
	local function plain_gsub(...)
		plain_gsub = require(m_str_utils).plain_gsub
		return plain_gsub(...)
    end
	
	local function safe_load_data(...)
		safe_load_data = require(m_load).safe_load_data
		return safe_load_data(...)
	end
	
	local function sc_get_by_code(...)
		sc_get_by_code = require(m_sc).getByCode
		return sc_get_by_code(...)
	end
	
	local function tag_text(...)
		tag_text = require(m_sc_utils).tag_text
		return tag_text(...)
	end

local function is_userpage()
	-- Categorization and tracking should be suppressed if the page is not a root user page.
	local title = mw.title.getCurrentTitle()
	return title:inNamespace("User") and title.text == title.rootText
end

local function soft_error(key, message)
	if is_userpage() then
		debug_track(key)
	end
	
	return '<span class="error">' .. message .. '</span>'
end

local function process(code)
	return
		gsub(code, "-$", ""),
		match(code, "-()$") or "N"
end

local message_memo = {}

local function grab_message(lang, proficiency, type)
	if message_memo then
		return message_memo
		
	elseif type == ("language" or "sign language") then
		local subpage = safe_load_data("Module:Babel/data/" .. sub(lang, 1, 1))
		
		if subpage and subpage then
			message_memo = subpage
			return message_memo, true -- The boolean indicates it's translated for tagging purposes.
		end
		
	elseif type == "script" then
		local message = load_data(m_data).script_messages
		
		if message then
			message_memo = message
			return message
		end
	end
		
	if not proficiency then
		error("Message for " .. lang .. " was not grabbed because proficiency was not provided.")
		
	else
		-- Fetch from /data based on type.
		
		message_memo = load_data(m_data)
		or soft_error("invalid proficiency", "Invalid proficiency: " .. proficiency)
	end
	
	return message_memo
end

local function special_table(code)
	if not code then
		return "align=center style=\"font-style:italic;\" | "
			.. "You haven't set up any languages. "
			.. "Please see ] for help."
			
	elseif code == "!" then
		return "\n|\n"
		
	elseif code == "-" then
		return "<div style=\"float: left; margin: 2px;\">\n"
			.. "{| cellspacing=\"0\" style=\"width: 238px;\"\n"
			.. "| style=\"width: 45px; height: 45px;\" | &nbsp;\n"
			.. "|style=\"font-size: 8pt; padding: 4pt; line-height: 1.25em;\" | &nbsp;\n|}</div>"
			
	elseif code == "----" then
		return "<div style=\"clear: both; padding: 0.25em 0;\"><hr/></div>"
		
	else
		
		--[[ This doesn't have the same checks as make_table, so it needs to
		be able to deal with the fact you can technically pass something like
		----- and bypass all the langcode checks. ]]
		
		error(code .. " is not a recognised feature; please see [[Template:"
			.. "Babel/documentation]] for a list of these.")
	end
end

local function generate_cats(lang, proficiency, type, script)
	if not lang then
		error("Categories could not be generated because language code was not provided.")
	
	elseif script then
		-- for example, ko-Kore should categorise as ko, ko-Kore, Kore
		return {
			"Category:User " .. lang .. "-" .. script .. "-" .. proficiency,
			"Category:User " .. lang .. "-" .. script,
			"Category:User " .. lang .. "-" .. proficiency,
			"Category:User " .. lang,
			"Category:User " .. script .. "-" .. proficiency,
			"Category:User " .. script,
		}
	
	else
		if type == "programming" then
			return {
				"Category:User " .. lang .. " coder-" .. proficiency,
				"Category:User " .. lang .. " coder",
			}
		end
		
		return {
			"Category:User " .. lang .. "-" .. proficiency,
			"Category:User " .. lang,
		}
	end
end

--[==[ This is where modules can interface with Babel. `data` is a table 
	 containing the following arguments:
		* `obj` '''usually required''': Language, script, or family object.
		* `lang`: Language code. This is '''required''' if obj is not passed.
		* `code` '''required''': Language code affixed with proficiency (or, if unaffixed, proficiency should be native).
		* `proficiency` '''required''': This can be 0, 1, 2, 3, 4, 5, or N.
		* `text` '''required''': Text to display in the box.
		* `type`: Used to determine what formatting to use. This is '''required''' if the box being generated is for a script, (non-sign) language, or programming language.
		* `glyph`: The glyph to show above the script code. This is '''required''' for scripts.
		* `prog_obj`: Programming language data from ]. This is '''required''' if the box being generated is for a programming language.
		* `translated`: Whether `text` is in English. If this is set to {true}, the text will be appropriately tagged with ].
	]==]
function export.generate_box(data)
	if not (data.obj or data.lang) then
		error("generate_box received neither `obj` nor `lang`.")
	elseif not (data.code and data.proficiency) then
		error("`code` and `proficiency` must be passed to generate_box.")
	end
	
	local lang = data.obj and data.obj:getCode() or data.lang
	
	local ret = '<div class="babel-box babel-' .. data.proficiency .. '">\n' ..
				'<table class="babel-content"><tr>'
	
	if data.type == "script" then
		if not data.glyph then
			error("Glyph must be passed to generate_box, because " .. lang .. " is a script code.")
		end
		
		if lang ~= "Latn" then
			if data.glyph == "A" then
				debug_track("Babel/missing script glyph")
			end
			
			if not find(lang, "PA") then
				data.glyph = tag_text(data.glyph, sc_get_by_code())
				
			else
				data.glyph = '<span class="IPA">' .. data.glyph .. '</span>'
			end
		end
		
		ret = ret .. '<td class="babel-code" style="font-size:9pt;line-height:100%>' ..
					 '<span style="font-size:14pt;line-height:130%;">' .. data.glyph ..
					 '</span><br><b>' .. data.code .. '</b></td><td class="babel-text">'
					 .. data.text .. '</span>'
		
	else
		if data.type == "programming" then
			data.link = "]" or ""
			data.text = plain_gsub(data.text, "|" .. lang, "|" .. (data.prog_obj.display or data.prog_obj.display_code or lang))
			
			if lang ~= data.code then
				data.link = data.link .. "-" .. data.proficiency
			end
			
		else
			if data.type == "language" then
				data.dir = "left"
				
				if obj and find(obj:findBestScript(data.text):getDirection(), "rtl") then
					data.dir = "right"
				end
				
				if data.script then
					lang = lang .. "-" .. data.script
				end
			end
			
			do
				-- Display what was inputted - en for en, en-N for en-N.
				local proficiency
				data.link = data.link or lang
				if data.link ~= data.code then
					proficiency = "-" .. data.proficiency
				end
				data.link = "]" .. (proficiency or "")
			end
			
			if data.obj and data.translated then
				local tagged = {}
				local n = 1
				
				for i in gmatch(gsub(data.text, "<r>", "\n"), "+") do
					tagged = tag_text(i, data.obj)
					n = n + 1
				end
				
				data.text = concat(tagged, match(data.text, "<r>"))
			end
		end
			
		ret = ret .. '<td class="babel-code" style="font-size:14pt;">' ..
					 '<b>' .. data.link .. '</b></td><td class="babel-text" style="text-align:' ..
					 (data.dir or "") .. ';">' .. data.text .. '</td>'
	end
	
	return ret
end

local function make_table(code, inactive)
	if not code or find(code, "^+$") then
		return special_table(code)
		
	elseif find(code, "UNIQ") then
		
		--[[ If it has a MW strip marker, it's probably a template or some
			 other rubbish that shouldn't be passed. ]]
		
		error("Do not pass a template as a parameter.")
	end
	
	local lang, proficiency = process(code)
	
	local data = { code = code, proficiency = proficiency, lang = lang }
	
	--[[ Data needs to have 4 things to be able to build the table:
			- `type` of table to make: language, script, proglang, or family
			- `message`, which is either fetched from /data or /data/...
			- `langname`, for $3 in the generic messages
			- `link`, to be displayed on the left
		 If the message is translated, it will also have an item `translated`
		 indicating that.
		 Script data will also have a glyph.
		 Programming languages will sometimes have custom codes to display, and,
		 for internal use only, a titlecase version of the name (e.g. Php for 
		 PHP, Asm for asm, etc.). ]]
	
	if find(lang, "-%u%l+$") then
		-- Allow language codes affixed with script codes.
		data.script = match(data.lang, "-(%u%l+)$")
		data.display_code = data.lang
		data.lang = gsub(data.lang, "-%u%l+$", "")
		if not sc_get_by_code(data.script) then
			return soft_error("invalid script code", "Invalid script code: " .. data.script)
		end
	end
	
	local type
	type, data.obj = next{
		language = lang_get_by_code(data.lang, nil, true),
		script = sc_get_by_code(data.lang),
		family = fam_get_by_code(data.lang),
	}
	
	if data.obj then
		data.langname = data.obj:getCanonicalName()
		data.type = type
		local is_sign_language = (type == "language" and data.obj:inFamily("sgn") and "sign_") or ""
		data.text, data.translated = grab_message(data.lang .. (data.script and "-" .. data.script or ""), proficiency, is_sign_language .. data.type)
		
	else
		data.titlecase = upper(sub(lang, 1, 1)) .. lower(sub(lang, 2, -1))
		local locations = {
			programming = load_data(m_data).proglangs,
			language = load_data(m_data).custom_codes,
			script = { 
				--[[ Invalid in Module:scripts but still used, so exceptions should
					 be made for these two. Probably should be phased out. ]]
				 = "IPA",
				 = "UPA",
			},
		}
		
		locations.script = locations.script
		locations.language = locations.language and locations.language
		
		local type, langname = next(locations)
		
		if type == "programming" then
			data.type = type
			data.text = grab_message(data.lang, data.proficiency, type)
			data.langname = data.lang
		
		elseif langname then
			data.type = type
			data.text, data.translated = grab_message(data.lang .. (data.script and "-" .. data.script or ""), data.proficiency, data.type)
			data.langname = langname
			if type == "language" then
				debug_track("custom code")
				data.obj = lang_get_by_code(load_data(m_data).custom_codes.fallback)
				data.link = data.lang
			end
			
		else
			return soft_error("invalid language code", "Invalid language code: " .. lang)
		end
	end
	
	if data.type == "script" then
		data.glyph = load_data(m_data).script_glyphs or "A"
	end
	
	if data.script then
		data.cats = generate_cats(data.obj:getCode(), data.proficiency, data.type, data.script)
	
	elseif data.type ~= "programming" then
		data.cats = generate_cats(data.obj and data.obj:getCode() or data.lang, data.proficiency, data.type)
		
	else
		data.prog_obj = load_data(m_data).proglangs
		data.cats = generate_cats((data.prog_obj.cat or data.prog_obj.display or data.titlecase), proficiency, data.type)
	end
	
	if not data.translated then
		data.text = gsub(data.text, "$1", ":" .. data.cats)
		data.text = gsub(data.text, "$2", ":" .. data.cats)
		data.text = gsub(data.text, "$3", data.langname)
			
	else
		data.text = gsub(data.text, "$1", ":" .. data.cats)
		data.text = gsub(data.text, "$2", ":" .. data.cats)
			
		if find(data.text, "{") then
			data.text = gsub(data.text, "{-}",
			-- Gender parsing.
			function(arg)
				if not find(arg, "%++%+*}") then 
					return soft_error("missing second delimiter", "Message " .. arg .. " missing second + delimiter: ", lang) 
				end
				
				local forms = {
					match(arg, "{(+)"),		-- masculine
					match(arg, "%+(+)%+"),	-- feminine
					match(arg, "(+)}")		-- neutral
				}
				
				return mw.getContentLanguage():gender(mw.title.getCurrentTitle().rootText, forms)
			end)
		end
		
		if find(data.text, "hiero") then
			data.text = mw.getCurrentFrame():preprocess(data.text)
		end
	end
	
	local ret = export.generate_box(data)
	
	if data.cats and is_userpage() and proficiency ~= "0" then
		if not inactive then
			ret = ret .. "]]"
			
		else
			for i = 1, #data.cats do
				ret = ret .. " .. " (inactive)]]"
			end
		end
	end
	
	return ret .. '</tr></table></div>'
end

--==]
function export.t_userbox(frame)
	local args = require(m_para).process(frame:getParent().args, {
		 = true,
		 = true,
	})
	return make_table(args, args)
end

--==]
function export.show(frame)
	local args = require(m_para).process(frame:getParent().args, {
		 = { list = true },
		 = { type = "boolean" },
		 = { set = { "left", "right", "none", "center" }, default = "right" },
		 = { alias_of = "float" },
		 = { default = "248px" },
		 = { default = "#99B3FF" },
		 = { default = "]" },
		 = { default = "inherit" },
		 = {
			default = "Search [[:Category:User languages|"
				.. "user languages]] or ]"
		},
		 = { alias_of = "border_color" },
		 = { alias_of = "border_color" },
		 = true,
		 = { alias_of = "gender" },
		 = { boolean = true },
	})

	local result = {}
	
	if not args then
		result = make_table()
		
	else
		for i = 1, #args do
			result = make_table(args, args)
		end
	end
	
	local colspan = #result
	
	result = concat(result, "")
	
	if args then
		return result
	end
	
	if args then
		args = args .. " <span title=\"This user has not "
			.. "contributed in 2 or more years.\">(inactive)</span>"
	end
	
	if args and require(m_pages).is_preview() then
		args = args .. "\n<span class=\"error\""
			.. "style =\"font-size:75%;\">"
			.. "Gender is automatically grabbed from your preferences.\n"
			.. "You can remove the gender parameter.</span>"
	end
	
	if args == "center" then
		debug_track("float center")
		args = "right"
	end
	
	return "{| class=\"babel-box-wrapper\" name=\"userboxes\" id=\"userboxes\""
		.. "style=\"float: " .. args .. "; margin-left: 1em;"
		.. "margin-bottom: 0.5em; width: " .. args .. "; border: "
		.. args .. " solid 1px;"
		.. "clear: " .. args .. ";\"\n"
		.. "! style=\"background-color: " .. args .. "; text-align:"
		.. "center\" colspan=\"10\" | " .. args .. "\n"
		.. "|- style=vertical-align:top\n"
		.. "|" .. result .. "\n"
		.. "|-\n| style=\"background-color: " .. args .. ";"
		.. "text-align: center;\" colspan=\"" .. colspan .. "\" | " .. args
		.. "\n|}"
end

return export