Module:Babel: difference between revisions

From Wiktionary, the free dictionary
Jump to navigation Jump to search
Content deleted Content added
mw.log() when bailing out
replace the "feral child" text with "Unknown.", per Equinox in Wiktionary:Requests_for_deletion/Others#Template:Babel/x
Line 474: Line 474:
table.insert(curr_column, make_box(
table.insert(curr_column, make_box(
'na', "???",
'na', "???",
"Unknown."
"This user is either a robot, an animal, or a [[w:feral child|feral child]] who speaks no languages. Assistance is required."
))
))
end
end

Revision as of 10:13, 30 March 2016


local export = {}

local m_languages = mw.loadData('Module:languages/alldata')
local m_wmf = mw.loadData('Module:wikimedia_languages/data')
local m_scripts = mw.loadData('Module:scripts/data')

local aliases = {
	-- languages
	["en-us"    ] = "en";
	["en-gb"    ] = "en";
	["en-uk"    ] = "en";

	-- scripts
	["IPA"      ] = "IPAchar";
	["polytonic"] = "Grek";

	-- tech
	["t"        ] = "temp";
	["template" ] = "temp";
}

local tech_boxes = {
	JS = {
		category = "JavaScript coder";
		blurbs = {
			[0] = "This user knows little about JavaScript and just mimics existing usage.";
			"This user knows the basics of how to write JavaScript code and make minor tweaks.";
			"This user has a fair command of JavaScript, and can understand some scripts written by others.";
			"This user can write more complex JavaScript code, and can understand and modify most scripts written by others.";
			"This user can write and understand all kinds of complex JavaScript code.";
			nil;
			"This user is a web browser.";
		}
	};

	Lua = {
		category = "Lua coder";
		blurbs = {
			[0] = "This user knows little about Lua and just mimics existing usage.";
			"This user knows the basics of how to use Lua modules in entries.";
			"This user can use Lua modules with ease, and can write some simple ones.";
			"This user can write more complex Lua modules.";
			"This user can write and understand very complex Lua code.";
			nil;
			"This user is a robot with a built-in Lua implementation.";
		}
	};

	temp = {
		badge = "{{t}}";
		category = "template coder";
		blurbs = {
			[0] = "This user knows little about wiki templates and just mimics existing usage.";
			"This user knows the basics of how to use wiki templates in entries.";
			"This user can use wiki templates with ease, and can write some simple ones.";
			"This user can write more complex wiki templates.";
			"This user can write and understand very complex wiki templates.";
			nil;
			"This user is a MediaWiki installation.";
		}
	};
}

local babel_lang_blurbs = {
	[0] = "This user '''does not understand''' %s (or understands it with considerable difficulty).";
	--  ↑ Lua sucks. Real programming languages count from zero by default.
	"This user is able to contribute with a '''basic''' level of %s.";
	"This user is able to contribute with an '''intermediate''' level of %s.";
	"This user is able to contribute with an '''advanced''' level of %s.";
	"This user speaks %s at a '''near-native''' level.";
	nil; -- level 5, reserved for "professional knowledge"
	"This user is a '''native speaker''' of %s.";
}

local babel_sc_blurbs = {
	[0] = "This user '''cannot read''' %s.";
	"This user has a '''basic understanding''' of '''%s'''.";
	"This user has '''intermediate understanding''' of '''%s'''.";
	"This user has '''advanced understanding''' of '''%s'''.";
	"This user has a '''near-native understanding''' of '''%s'''.";
	nil; -- level 5 is probably never going to be used with scripts, but reserving for the sake of simple code
	"This user's '''native script''' is '''%s'''.";
}

local badge_color = {
	[0] = "#FFB3B3"; "#C0C8FF"; "#77E0E8"; "#99B3FF"; "#CCCC00"; nil; "#6EF7A7"; na = "#CCCCCC";
}

local blurb_color = {
	[0] = "#FFE0E8"; "#F0F8FF"; "#D0F8FF"; "#E0E8FF"; "#FFFF99"; nil; "#C5FCDC"; na = "#EEEEEE";
}

local function make_box(level, badge, blurb)
	-- XXX: get rid of inline styles
	return ([=[
! style="width: 36px; height: 36px; padding: 8px; background:%s; text-align:center;font-size:14pt" |%s
| style="width: 180px; font-size:8pt; padding:4pt; line-height:1.25em; background: %s" |%s
]=]):format(
		badge_color[level], badge,
		blurb_color[level], blurb
	)
end

local function bailout(frame)
	-- ABANDON SHIP
	return frame:expandTemplate { title = "Babel/old"; args = frame:getParent().args }
end

-- XXX: split off into a data module
local script_data = {
	["Arab"] = {
		badge = "ض";
		name = "the Arabic abjad";
	};

	["Armn"] = {
		badge = "Ճ";
		name = "the Armenian alphabet";
	};

	["Beng"] = {
		badge = "ফ";
		name = "the Bengali script";
	};

	["Bopo"] = {
		badge = "ㄅ";
		name = "Zhuyin";
	};

	["Bugi"] = {
		badge = "ᨒ";
		name = "Lontara";
	};

	["Cher"] = {
		badge = "Ꮙ";
		name = "the Cherokee syllabary";
	};

	["Cyrl"] = {
		badge = "Я";
		name = "the Cyrillic alphabet";
	};

	["Cyrs"] = {
		badge = "ѣ";
		name = "the old Cyrillic alphabet";
	};

	["Deva"] = {
		badge = "छ";
		name = "Devanagari";
	};

	["Dsrt"] = {
		badge = "𐐒";
		name = "Deseret alphabet";
	};

	["Egyp"] = {
		badge = "[[File:Egyptian-A.PNG]]";
		name = "Egyptian hieroglyphics";
	};

	["Geor"] = {
		badge = "ლ";
		name = "the Georgian alphabet";
	};

	["Glag"] = {
		badge = "Ⰴ";
		name = "the Glagolitic alphabet";
	};

	["Goth"] = {
		badge = "𐌰";
		name = "the Gothic alphabet";
	};

	["Grek"] = {
		badge = "Ω";
		name = "the Greek alphabet";
	};

	["Gujr"] = {
		badge = "ભ";
		name = "the Gujarati script";
	};

	["Guru"] = {
		badge = "ਝ";
		name = "the Gurmukhi script";
	};

	["Hang"] = {
		badge = "글";
		name = "Hangeul";
	};

	["Hani"] = {
		badge = "漢";
		name = "Hanzi";
	};

	["Hans"] = {
		badge = "简";
		name = "Simplified Chinese";
	};

	["Hant"] = {
		badge = "繁";
		name = "Traditional Chinese";
	};

	["Hebr"] = {
		badge = "ש";
		name = "the Hebrew script";
	};

	["Hira"] = {
		badge = "か";
		name = "Hiragana";
	};

	["IPA"] = {
		badge = "/ʑ/";
		name = "the International Phonetic Alphabet";
	};

	["Java"] = {
		badge = "ꦙ";
		name = "Javanese";
	};

	["Jpan"] = {
		badge = "蓮";
		name = "the Japanese script";
	};

	["Kana"] = {
		badge = "タ";
		name = "Katakana";
	};

	["Khmr"] = {
		badge = "ខ";
		name = "the Khmer script";
	};

	["Knda"] = {
		badge = "ತಃ";
		name = "Kannada";
	};

	["Laoo"] = {
		badge = "ຊ";
		name = "the Lao script";
	};

	["Latn"] = {
		badge = "A";
		name = "the Latin alphabet";
	};

	["Maya"] = {
		badge = "[[File:Ixchel.svg|50px]]";
		name = "Maya hieroglyphics";
	};

	["Mlym"] = {
		badge = "അ";
		name = "Malayalam";
	};

	["Mymr"] = {
		badge = "မ";
		name = "the Burmese script";
	};

	["Ogam"] = {
		badge = "ᚑ";
		name = "the Ogham script";
	};

	["Orya"] = {
		badge = "ଢ";
		name = "the Oriya script";
	};

	["Runr"] = {
		badge = "ᚠ";
		name = "the Runic alphabet";
	};

	["Shaw"] = {
		badge = "[[Image:Shavian Hung.svg|20px]]";
		name = "Shavian alphabet";
	};

	["Sinh"] = {
		badge = "ස";
		name = "the Sinhalese script";
	};

	["Sund"] = {
		badge = "ᮚ";
		name = "Sundanese";
	};

	["Syrc"] = {
		badge = "ܐ";
		name = "Syriac";
	};

	["Tale"] = {
		badge = "ᥞ";
		name = "the Tai Le script";
	};

	["Talu"] = {
		badge = "ᦐ";
		name = "the New Tai Lue script";
	};

	["Taml"] = {
		badge = "ஞ";
		name = "Tamil script";
	};

	["Telu"] = {
		badge = "ణ";
		name = "Telugu";
	};

	["Teng"] = {
		badge = "[[Image:Tengwa anga.svg|20px]]";
		name = "Tengwar";
	};

	["Tfng"] = {
		badge = "ⵣ";
		name = "Tifinagh script";
	};

	["Thai"] = {
		badge = "ซ";
		name = "the Thai script";
	};

	["Tibt"] = {
		badge = "ཀ";
		name = "the Tibetan script";
	};

	["Xpeo"] = {
		badge = "𐎠";
		name = "Old Persian cuneiform script";
	};

	["Xsux"] = {
		badge = "𒈠";
		name = "Sumero-Akkadian cuneiform";
	};
}

function export.make_tower(frame)
	local curr_column = {}
	local columns = { curr_column }
	local categories = {}
	local height = 0

	local function add_language_box(lang_code, level)
		local name = m_languages[lang_code].canonicalName
		local wmf_code = m_languages[lang_code].wikimedia_codes and m_languages[lang_code].wikimedia_codes[1] or lang_code
		local lang_native_name = frame:callParserFunction("#language", wmf_code, wmf_code)
		
		table.insert(curr_column, make_box(
			level,
			lang_native_name
				and ('<abbr title="%s">%s</abbr>%s'):format(lang_native_name, lang_code, (level == 6) and "" or ("-" .. level))
				or (lang_code .. ((level == 6) and "" or ("-" .. level))),
			babel_lang_blurbs[level]:format(name)
		))

		if level >= 1 then
			table.insert(categories, "User " .. ((level == 6) and (lang_code .. "-N") or (lang_code .. "-" .. level)))
			table.insert(categories, "User " .. lang_code)
		end
	end

	local function add_script_box(sc_code, level)
		sc_code = sc_code:match("^[a-z]*%-([A-Z][a-z][a-z][a-z])$") or sc_code

		if sc_code == "IPAchar" then -- XXX: hack
			sc_code = "IPA"
		end

		local scinfo = script_data[sc_code] or {}
		local name = scinfo.name or m_scripts[sc_code].canonicalName

		table.insert(curr_column, make_box(
			level, (scinfo.badge and ('<span class="' .. sc_code .. '" style="font-weight:normal;font-size:1.4em;">' .. scinfo.badge .. '</span><br/>') or "") .. ((level == 6) and sc_code or (sc_code .. "-" .. level)),
			babel_sc_blurbs[level]:format(name)
		))

		if level >= 1 then
			table.insert(categories, "User " .. ((level == 6) and (sc_code .. "-N") or (sc_code .. "-" .. level)))
		end
	end

	local function add_tech_box(tech_code, level)
		local tech_info = tech_boxes[tech_code]
		local badge = tech_info.badge or tech_code

		table.insert(curr_column, make_box(
			level, (level == 6) and badge or (badge .. "-" .. level),
			tech_info.blurbs[level]
		))

		if level >= 1 then
			table.insert(categories, "User " .. tech_info.category .. ((level == 6) and "-4" or ("-" .. level)))
		end
	end

	for _, boxspec in ipairs(frame:getParent().args) do
		if boxspec == "!" then
			curr_column = {}
			columns[#columns + 1] = curr_column
		elseif boxspec == "-" then
			table.insert(curr_column, ' | colspan="2" style="height: 36px; padding: 8px;" |\n')
		elseif boxspec == "----" then
			table.insert(curr_column, ' | colspan="2" |<hr />\n') -- XXX
		else
			local lang, level = boxspec:match("^([A-Za-z][A-Za-z%-]-)%-([01234N])$")
			if lang then
				level = tonumber(level) or 6
			else
				lang = boxspec:match("^([A-Za-z][A-Za-z%-]-)$")
				level = 6
			end

			local langname
			if lang then
				if aliases[lang] then
					lang = aliases[lang]
				end

				if m_languages[lang] then
					add_language_box(lang, level, curr_column, categories)
				elseif m_wmf[lang] then
					add_language_box(m_wmf[lang].wiktionary_code, level, curr_column, categories)
				elseif m_scripts[lang] then
					add_script_box(lang, level, curr_column, categories)
				elseif tech_boxes[lang] then
					add_tech_box(lang, level, curr_column, categories)
				else
					mw.log(("Unknown code '%s'"):format(lang))
					return bailout(frame)
				end
			else
				mw.log(("No idea how to interpret '%s'"):format(boxspec))
				return bailout(frame)
			end
		end

		if #curr_column > height then
			height = #curr_column
		end
	end

	if height == 0 then
		height = 1
		table.insert(curr_column, make_box(
			'na', "???",
			"Unknown."
		))
	end

	local output = {}
	local args = frame:getParent().args

	output[#output + 1] = ('{| style="border: 1px solid silver; padding: 2px; float: %s; clear: %s;"\n'):format(args.align or "right", args.align or "right")
	output[#output + 1] = ("|+ '''%s'''\n"):format(args.header or "[[Wiktionary:Babel|Babel]]")
	
	for i = 1, height do
		table.insert(output, " |-\n")
		for _, column in ipairs(columns) do
			if column[i] then
				table.insert(output, column[i])
			else
				table.insert(output, ' | colspan="2" |\n')
			end
		end
	end

	if args.footer then
		output[#output + 1] = ('|-\n | colspan="%u" style="text-align: center;" |%s\n'):format(2 * #columns, args.footer)
	end

	table.insert(output, " |}")

	if mw.title.getCurrentTitle().namespace == mw.site.namespaces.User.id then
		for _, cat in ipairs(categories) do
			table.insert(output, "[[Category:" .. cat .. "]]")
		end
	end

	return table.concat(output)
end

return export