Module:Class

-- This module implements Template:Class, Template:Class/icon and -- Template:Class/colour.

local mArguments, mIcon -- modules to lazily load local definitions = mw.loadData('Module:Class/importDefinitions')

local p = {}

-- Initialize helper function variables local getDefinition, getRawArgs, makeInvokeFunction, normalizeValue

-- Argument helper functions

function getRawArgs(frame, wrapper) mArguments = mArguments or require('Module:Arguments') return mArguments.getArgs(frame, {		wrappers = wrapper,		trim = false,		removeBlanks = false	}) end

function makeInvokeFunction(func, wrapper) return function (frame) local args = getRawArgs(frame, wrapper) return func(args) end end

-- String helper functions

function trim(str) if type(str) == 'string' then str = str:match('^%s*(.-)%s*$') end return str end

function normalizeValue(val) if type(val) == 'string' then val = trim(val):lower end if val == '' then val = nil end return val end

function ucfirst(str) return mw.ustring.upper(mw.ustring.sub(str, 1, 1)) .. mw.ustring.sub(str, 2) end

-- Definition helper functions

function getDefinition(code) local canonicalCode = normalizeValue(code) if code == 'DEFAULT' then canonicalCode = code end --DEFAULT special-case local class = definitions[canonicalCode] while class and class.alias do		canonicalCode = class.alias class = definitions[class.alias] end if not class then return nil, nil end return class, canonicalCode end

function getDefault return getDefinition('DEFAULT') end

function getProperty(class, default, map) local pop = table.remove(map, 1) local prop, dProp = class and class[pop], default and default[pop] while #map > 0 do		pop = table.remove(map, 1) prop = ((type(prop) == 'table') or nil) and prop[pop] dProp = ((type(dProp) == 'table') or nil) and dProp[pop] end if prop == nil then prop = dProp end return prop end

-- Color functions

function p._colour(code) return getProperty(getDefinition(code), getDefault, {'colour', 'base'}) end

function p.colour(frame) local args = getRawArgs(frame, 'Template:Class/colour') local colour = p._colour(args[1]) -- We need nowiki tags as template output beginning with "#" triggers -- bug 14974. return frame:extensionTag('nowiki', colour) end

-- Icon functions

function p._icon(args) local class = getDefinition(args.class or args[1]) local default = getDefault local file = getProperty(class, default, {"icon", "file"}) local label = getProperty(class, default, {"labels", "full"}) label = ucfirst(label) local attrib = getProperty(class, default, {"icon", "requiresAttribution"}) local span = mw.html.create('span')

span :cssText(args.style) :attr('title', label) :wikitext(			string.format( '',				file, label, attrib and '' or '|link=|alt=' )		)	return tostring(span) end

p.icon = makeInvokeFunction(p._icon, 'Template:Class/icon')

-- Class functions

function p._class(args) local classDef, classCode = getDefinition(args.class or args[1]) local default = getDefault local iconDefault = getProperty(classDef, default, {"icon", "default"}) local shortLabel = getProperty(classDef, default, {"labels", "short"}) local categoryRoot = getProperty(classDef, default, {"categoryRoot"}) --o is short for "options", go for "get options". Bool true → case-sensitive local o, go = {}, { bold = false, heading = false, image = false, rowspan = false, fullcategory = true, category = true, topic = true }	for k, v in pairs(go) do		if v then o[k] = trim(args[k]) else o[k] = normalizeValue(args[k]) end end

local cell = mw.html.create(o.heading and 'th' or 'td') --image=yes forces icon, image=no disables it, otherwise checks default local icon = iconDefault and (o.image ~= 'no') or (o.image == 'yes') icon = icon and p.icon(args) .. ' ' or ''

local category if o.fullcategory then category = o.fullcategory elseif o.category then category = string.format('%s %s', categoryRoot, o.category) elseif o.topic then category = string.format('%s %s articles', categoryRoot, o.topic) else category = string.format('%s articles', categoryRoot) end local text = string.format ('%s', category, shortLabel) cell :addClass('assess') :addClass('assess-' .. (classCode or '')) :css('text-align', 'center') :css('white-space', 'nowrap') :css('font-weight', o.bold ~= 'no' and 'bold' or nil) :css('background', p._colour(classCode)) :attr('rowspan', tonumber(o.rowspan)) :wikitext(icon, text)

return tostring(cell) end

p.class = makeInvokeFunction(p._class, 'Template:Class')

return p