Module:User:Wyang/zh-def

From Wiktionary, the free dictionary
Jump to navigation Jump to search

This is a private module sandbox of Wyang, for their own experimentation. Items in this module may be added and removed at Wyang's discretion; do not rely on this module's stability.


local export = {}
local match = mw.ustring.match
local gsub = mw.ustring.gsub
local sub = mw.ustring.sub
local len = mw.ustring.len

function export.main(frame)
	local m_zh = require("Module:zh")
	local m_links = require("Module:links")
	local availableParam = {}
	local args = frame:getParent().args
	local senses = { [1] = { ["examples"] = {} }}
	
	local mods = {
		["syn"] = true, 
		["ant"] = true, 
		["also"] = true, 
		["mw"] = true, 
		["dial"] = true,
		["lb"] = true
	}
	
	i = 1
	for _, arg in ipairs(args) do
		arg = gsub(arg, "\n$", "")
		if arg ~= "-" then
			if match(arg, "^...?.?: ") and mods[match(arg, "^[^:][^:][^:]?[^:]?")] then
				senses[i][match(arg, "^[^:][^:][^:]?[^:]?")] = match(arg, "^...?.?: (.+)")
				
			elseif match(arg, "^x[0-9]+: ") then
				table.insert(senses[i]["examples"], tostring( mw.html.create( "dd" ):wikitext( match(arg, "^x[0-9]+: (.+)") )))
				
			else
				senses[i][#senses[i] + 1] = arg
			end
		else
			i = i + 1
			senses[i] = { ["examples"] = {} }
		end
	end
	
	local paramSubset = {
		{ 1, 1, "pos", nil },
		{ 2, 2, "definition", nil },
		{ 3, "mw", "cls", "[cls.]" },
		{ 4, "dial", "dial", "[dial.]" },
		{ 5, "syn", "syn", "[syn.]" },
		{ 6, "ant", "ant", "[ant.]" },
		{ 7, "also", "also", "[also]" },
		{ 8, "lb", "lb", nil },
	}
	table.sort(paramSubset, function(first, second) return first[1] < second[1] end)
	
	local function makeClassifier(text)
		if not text then return nil end
		local lang_abbrev = {
			["m"] = "Mandarin",
			["c"] = "Cantonese", ["g"] = "Gan", ["h"] = "Hakka", ["j"] = "Jin",
			["md"] = "Min Dong", ["mn"] = "Min Nan", ["mn-t"] = "Teochew",
			["w"] = "Wu", ["x"] = "Xiang",
		}
		
		local result, categories = {}, {}
		local m_zh_cat = require("Module:zh-cat")
		
		for combination in mw.text.gsplit(text, ",") do
			local varieties = match(combination, "^([^:]+):") or nil
			local remaining = match(combination, "^[^:]+:(.+)") or combination
			local classifier = match(remaining, "^[^%-]+") or nil
			local gloss = match(remaining, "^[^%-]+%-(.+)") or nil
			
			local dialectTags = {}
			if varieties then
				for variety in mw.text.gsplit(varieties, "+") do
					table.insert(dialectTags, lang_abbrev[variety])
				end
			end
			
			table.insert(result, 
				m_zh.link(frame, nil, { classifier, tr = "-" }, pagename) ..
				(varieties
					and (tostring( mw.html.create( "span" )
						:css( "padding-left", ".5em" )
						:css( "color", "#105E02" )
						:css( "font-size", "80%" )
						:wikitext( "[" .. table.concat( dialectTags ) .. 
							(gloss and " – " .. gloss or "") .. "]" )))
						
					or "" ))
				
			table.insert(categories, m_zh_cat.categorize("Classifier:" .. classifier))
		end
		return table.concat(result, ", ") .. (mw.title.getCurrentTitle().nsText == "" and table.concat(categories) or "")
	end
	
	
	local function makePoS(text)
		local pos_aliases = {
			["n"] = "noun", 
			["pn"] = "proper noun",
			["v"] = "verb", 
			["a"] = "adjective",
			["adv"] = "adverb",
			["postp"] = "postposition", 
			["conj"] = "conjunction", 
			["part"] = "particle", 
			["pron"] = "pronoun", 
			["prov"] = "proverb", 
			["id"] = "idiom", 
			["cy"] = "[[chengyu]]", 
			["ph"] = "phrase", 
			["intj"] = "interjection", 
			["abb"] = "abbreviation", 
			["cl"] = "classifier", 
			["deter"] = "determiner",
		}
		
		local pos_set = {}
		for pos in mw.text.gsplit(text, ",") do
			table.insert(pos_set, pos_aliases[pos])
		end
		return tostring( mw.html.create( "span" )
			:css( "padding-right", ".6em" )
			:css( "color", "#5A5C5A" )
			:css( "font-size", "80%" )
			:wikitext( "[" .. table.concat(pos_set) .. "]" ))
	end
	
	local function makeLabel(label_text)
		if not label_text then return "" end
		local lang = require("Module:languages").getByCode("zh")
		local labels = require("Module:labels").show_labels(mw.text.split(label_text, "+"), lang)
		return 
		tostring( mw.html.create( "span" )
			:css( "padding-right", ".6em" )
			:css( "color", "#105E02" )
			:css( "font-size", "80%" )
			:wikitext( 
				tostring(mw.html.create( "span" ):wikitext( "[" )) .. 
				sub(labels, 56, -38 ) ..
				tostring(mw.html.create( "span" ):wikitext( "]" ))))
	end
	
	local function makeDialectal(text)
		if not text then return nil end
		local dialectEquiv = {}
		local m_zh_dial = require("Module:zh-dial-syn/inline")
		for dialWord in mw.text.gsplit(text, ",") do
			table.insert(dialectEquiv, 
				tostring( mw.html.create( "dd" )
				:wikitext( m_zh_dial.main( dialWord ))))
		end
		return tostring( mw.html.create( "dl" )
			:wikitext( table.concat( dialectEquiv )))
	end
	
	local def_text = {}
	for sense_i, sense in ipairs(senses) do
		local availableParam, sense_text, p = {}, {}, {}
	
		for _, data in pairs(paramSubset) do
			p[data[3]] = sense[data[2]] or nil
			table.insert(availableParam, sense[data[2]] and data[4] or nil)
		end
		
		if #sense["examples"] > 0 then
			table.insert(availableParam, "[ex.]")
		end
		
		local function makeOther(text, class, no_plural, additional_text)
			if not text and not additional_text then return "" end
			local word_set = {}
			if not additional_text then
				for word in mw.text.gsplit(text, ",") do
					table.insert(word_set, 
						tostring(mw.html.create( "span" )
						:css( "padding-right", ".6em")
						:wikitext( m_zh.link(frame, nil, mw.text.split( "*" .. word, ":" )))))
				end
			end
			word_set = additional_text == "" and sense["examples"] or word_set
			return 
			tostring( mw.html.create( "dd" )
			:wikitext( 
				tostring( mw.html.create( "span" )
				:css( "padding-right", ".6em" )
				:css( "color", "#8F390A" )
				:css( "font-weight", "bold" )
				:css( "font-size", "90%")
				:wikitext( 
					tostring( mw.html.create( "span" )
					:css( "border-radius", "5px" )
					:css( "border", "solid #C0C2C0 1px" )
					:css( "padding", "3px" )
					:wikitext( "<tt>" .. class .. ((#word_set > 1 and not no_plural) and "s" or "") .. "</tt>" )))) ..
				
				(additional_text or table.concat(word_set))))
		end
	
		rand = gsub(
			math.ceil(math.random() * 100000000) .. sub(p["definition"], 1, 100),
			"[^A-Za-z0-9]",
			mw.ustring.codepoint("%1"))
		
		table.insert(sense_text, (sense_i ~= 1 and "\n" or "") .. "# ")
		
		table.insert(sense_text, 
			tostring( mw.html.create( "div" )
			:attr( "title", "expand" )
			:attr( "class", "mw-customtoggle-" .. rand )
			:css( "background", "#FAF8F2" )
			:css( "line-height", "200%" )
			:wikitext( 
				makePoS( p["pos"] ) .. 
				makeLabel( p["lb"] ) ..
				m_links.english_links(p["definition"]) .. 
					tostring( mw.html.create( "span" )
					:css( "float", "right" )
					:css( "font-size", "100%" )
					:wikitext( 
						tostring( mw.html.create( "span" )
						:css( "padding-right", ".5em" )
						:css( "color", "#105E02" )
						:css( "font-size", "90%" )
						:wikitext( table.concat( availableParam, " " ))) .. 
							( #availableParam > 0 and "▼" or "" ))))))

		if #availableParam > 0 then
			table.insert(sense_text, 
				tostring( mw.html.create( "div" )
				:attr( "class", "mw-collapsible mw-collapsed mw-collapsible-content" )
				:attr( "id", "mw-customcollapsible-" .. rand )
				:css( "line-height", "250%" )
				:css( "background-color", "#f9f9f9" )
				:wikitext(
					tostring( mw.html.create( "dl" )
					:wikitext(
						makeOther( p["cls"], "Classifier", false, makeClassifier( p["cls"] )) ..
						makeOther( p["syn"], "Synonym" ) ..
						makeOther( p["ant"], "Antonym" ) ..
						makeOther( p["also"], "See also", true ) ..
						makeOther( p["dial"], "Dialectal equivalents", false, makeDialectal( p["dial"] )) ..
						( #sense["examples"] > 0 
							and 
								makeOther( nil, "Example", false, "" ) ..
								tostring( mw.html.create( "dl" ):wikitext( table.concat( sense["examples"] ))) 
							or "" ))))))
		end
		table.insert(def_text, table.concat(sense_text))
	end
	
	return table.concat(def_text, "")
end

return export