Module:Background

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

Please see Template:Background to get a thorough understanding of what this module does.

Code

-- see also Module:File for related functions (protected editing only)
-- 2015-03-20: does not work currently, since mw.text.unstrip()
--             has been broken by Scribunto developers such that
--             <ref> markers are converted to an empty string rather
--             than html markup

-- note to MediaWiki developers:
--	please render this Module obsolete by just supporting this out of the box
--	see [[Template:Background]] for intended syntax (essentially support
--		color names without enforcing usage of a named argument for this)

-- to test within lua console:
--  local frame = mw.getCurrentFrame()
--  frame.args = { '[[File:Cercle blanc 100%.svg|black|right|white circle]]' }
--  =p.image(frame)

p = {}	-- exported table, this /is/ our module

cl = {	-- see Module:Colors for details
	d = function( s ) return mw.loadData( 'Module:Colors/data' )[s] end,
	r = function( s ) return cl.d(s)[1] end,
	g = function( s ) return cl.d(s)[2] end,
	b = function( s ) return cl.d(s)[3] end,
	isColorName = function( s ) return cl.d(s) ~= nil end,
	getHex      = function( s ) if not (s:sub( 1, 1 ) == '#')
		then if cl.isColorName(s)
			then s = cl.d(s)
				s = string.format( '#%02x%02x%02x', s[1], s[2], s[3] )
			else s = nil
			end
		end
		return s
	end
}

function set( t )
	local set = {}
	for k, v in pairs( t )
	do if k == "default" then set[k] = v else set[v] = true end
	end
	return set
end

function p.getArgs( frame )
	local a = frame.args

	if frame.getParent and mw.title.getCurrentTitle().subjectNsText ~= 'Module'
	then a = frame:getParent().args
	end

	-- lowercase argument names
	for k, v in pairs( a )
	do if type(k) == "string" then a[k:lower()] = v end
	end
	
	-- map alternative argument names
	for k, v in pairs( frame.alt_arg_names )
	do for vk, _ in pairs( v )
		do if a[vk] and _ == true then a[k] = a[vk] end
		end
		
		-- assign nil parms a default if given or the empty string
		if not a[k] then a[k] = v.default or "" end
	end
	
	frame.args = a
end

function p.image( frame )
	frame.alt_arg_names = {
		bg = set{ 'bg', 'background', 'bgcolor', 'bgcolour',
			'background-color', 'background-colour',
			'hintergrund', 'hintergrund-farbe', default = '#e0e0e0' }
	}
	p.getArgs( frame )
	
	strip_color = function( s )
		local a, c = nil, nil
		for m in s:gmatch( '%f[|]..-%f[]|]' )
		do a = mw.text.trim( m, '|%s' )
			if a:find( '=', 1, true )
			then a = mw.text.split( a, '%s*=%s*' )
				if frame.alt_arg_names.bg[a[1]] then c = a[2] end
			else c = c or cl.getHex( a )
			end
			if c
			then s = s:gsub( m, '', 1 )
				-- only consume a single color spec
				break
			end
		end
		return s, c or frame.args.bg
	end
	
	strip_other = function( s )
		local b, t, c = nil, nil, nil
		for _, v in ipairs{ 'border', 'rahmen' }
		do s, c = s:gsub( '|%s*' .. v .. '%s*%f[]|]', '' )
			if c > 0 then b = '|border' end
		end
		for _, v in ipairs{ 'thumb', 'thumbnail', 'mini', 'miniatur' }
		do s, c = s:gsub( '|%s*' .. v .. '%s*%f[]|]', '' )
			if c > 0 then t = '|thumb' end
		end
		for _, v in ipairs{ 'left', 'right', 'links', 'rechts' }
		do s, c = s:gsub( '|%s*' .. v .. '%s*%f[]|]', '' )
		end
		return s, b, t
	end
	
	restore_caption = function( mf )
		return function( s, t )
			return s .. mf:gsub( '^.*|([^|]-%b[][^|]*).-]]', '%1' ) .. t
		end
	end
	
	restore_mwlink = function( mf, border, thumb, color )
		local ft = {
			function( s ) -- magnify clip img (is a data blob in stylesheet now)
				return '[[:' .. mf:gsub( '^.-(File:.-)%f[]|].*$', '%1' ) .. ']]'
			end,
			function( s ) -- mwlink img
				if not mf:match( 'px%f[]|]' )
				then s = mf:gsub( '%f[]|]', s:gsub(
					'^.*%swidth="(.-)".*%sheight="(.-)".*$', '|%1x%2px' ) )
				else s = mf
				end
				s = mw.html.create('div')
					:attr( 'style', 'display:-moz-inline-stack;' ..
						'display:inline-block;zoom:1;*display:inline' )
					:wikitext( s )
				if border then s = s:addClass( 'thumbborder' ) end
				if thumb or border then s = s:addClass( 'thumbimage' ) end
				if color then s = s:css( 'background', color ) end
				return tostring( s )
			end
		}
		
		return function( s )
			local r = ft[ #ft ]( s )
			ft[ #ft ] = nil
			return r
		end
	end

	-- get mediafile ..
	local mf = frame.args[1]

	-- or build a wikilink if not passed complete as first argument
	if not mf:match( '^%s*%[%[%w+:' )
	then mf = "[[File"
		for _, v in ipairs( frame.args )
		do if not v:match( '^%s*$' )
			then mf = mf .. '|' .. v
			end
		end
		mf = mf:gsub( '|', ':', 1 ) .. ']]'
	end
	
	-- there should be a function to parse wikilinks into html ..
	local mf, color = strip_color( mf )
	local f = frame:newChild{ title = frame:getTitle(), args = { } }
	local _ = f:callParserFunction( '#tag:ref', mf )
	local mf, border, thumb = strip_other( mf )
	
	return mw.text.unstrip( f:preprocess('<references/>') )
		:gsub( '^.-<span.-reference%-text.->(.*)</span>.-$', '%1' )
		:gsub( '(</div>).-LINK.-(</div></div></div>)$', restore_caption( mf ) )
		:gsub( '(</div>).-<a.-(</div></div></div>)$', restore_caption( mf ) )
		:gsub( '<a[^>]*>.-</a[^>]*>%s*',
			restore_mwlink( mf, border, thumb, color )
		):sub( 1 ) -- do not append number of substitutions to returned string
end

return p