<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.limswiki.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AFile_link</id>
	<title>Module:File link - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.limswiki.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AFile_link"/>
	<link rel="alternate" type="text/html" href="https://www.limswiki.org/index.php?title=Module:File_link&amp;action=history"/>
	<updated>2026-04-04T17:07:54Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://www.limswiki.org/index.php?title=Module:File_link&amp;diff=38262&amp;oldid=prev</id>
		<title>Shawndouglas: Protected &quot;Module:File link&quot; ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</title>
		<link rel="alternate" type="text/html" href="https://www.limswiki.org/index.php?title=Module:File_link&amp;diff=38262&amp;oldid=prev"/>
		<updated>2020-03-10T19:04:51Z</updated>

		<summary type="html">&lt;p&gt;Protected &amp;quot;&lt;a href=&quot;/index.php/Module:File_link&quot; title=&quot;Module:File link&quot;&gt;Module:File link&lt;/a&gt;&amp;quot; ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:04, 10 March 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Shawndouglas</name></author>
	</entry>
	<entry>
		<id>https://www.limswiki.org/index.php?title=Module:File_link&amp;diff=38261&amp;oldid=prev</id>
		<title>Shawndouglas: Updated</title>
		<link rel="alternate" type="text/html" href="https://www.limswiki.org/index.php?title=Module:File_link&amp;diff=38261&amp;oldid=prev"/>
		<updated>2020-03-10T19:04:41Z</updated>

		<summary type="html">&lt;p&gt;Updated&lt;/p&gt;
&lt;a href=&quot;https://www.limswiki.org/index.php?title=Module:File_link&amp;amp;diff=38261&amp;amp;oldid=16563&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Shawndouglas</name></author>
	</entry>
	<entry>
		<id>https://www.limswiki.org/index.php?title=Module:File_link&amp;diff=16563&amp;oldid=prev</id>
		<title>Shawndouglas: Created as needed.</title>
		<link rel="alternate" type="text/html" href="https://www.limswiki.org/index.php?title=Module:File_link&amp;diff=16563&amp;oldid=prev"/>
		<updated>2014-11-22T16:39:12Z</updated>

		<summary type="html">&lt;p&gt;Created as needed.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- This module provides a library for formatting file wikilinks.&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require('libraryUtil')&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
&lt;br /&gt;
local fileLink = {}&lt;br /&gt;
&lt;br /&gt;
function fileLink.new(filename)&lt;br /&gt;
	checkType('fileLink.new', 1, filename, 'string', true)&lt;br /&gt;
	local obj, data = {}, {}&lt;br /&gt;
	&lt;br /&gt;
	local checkSelf = libraryUtil.makeCheckSelfFunction(&lt;br /&gt;
		'fileLink',&lt;br /&gt;
		'fileLink',&lt;br /&gt;
		obj,&lt;br /&gt;
		'fileLink object'&lt;br /&gt;
	)&lt;br /&gt;
	&lt;br /&gt;
	-- Set the filename if we were passed it as an input to fileLink.new.&lt;br /&gt;
	if filename then&lt;br /&gt;
		data.theName = filename&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:name(s)&lt;br /&gt;
		checkSelf(self, 'name')&lt;br /&gt;
		checkType('fileLink:name', 1, s, 'string')&lt;br /&gt;
		data.theName = s&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:format(s, filename)&lt;br /&gt;
		checkSelf(self, 'format')&lt;br /&gt;
		checkType('fileLink:format', 1, s, 'string', true)&lt;br /&gt;
		checkType('fileLink:format', 2, format, 'string', true)&lt;br /&gt;
		local validFormats = {&lt;br /&gt;
			thumb = true,&lt;br /&gt;
			thumbnail = true,&lt;br /&gt;
			frame = true,&lt;br /&gt;
			framed = true,&lt;br /&gt;
			frameless = true&lt;br /&gt;
		}&lt;br /&gt;
		if s == nil or validFormats[s] then&lt;br /&gt;
			data.theFormat = s&lt;br /&gt;
			data.theFormatFilename = filename&lt;br /&gt;
		else&lt;br /&gt;
			error(string.format(&lt;br /&gt;
				&amp;quot;bad argument #1 to 'fileLink:format' ('%s' is not a valid format)&amp;quot;,&lt;br /&gt;
				s&lt;br /&gt;
			), 2)&lt;br /&gt;
		end&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function sizeError(methodName)&lt;br /&gt;
		-- Used for formatting duplication errors in size-related methods.&lt;br /&gt;
		error(string.format(&lt;br /&gt;
			&amp;quot;duplicate size argument detected in '%s'&amp;quot;&lt;br /&gt;
			.. &amp;quot; ('upright' cannot be used in conjunction with height or width)&amp;quot;,&lt;br /&gt;
			methodName&lt;br /&gt;
		), 3)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:width(px)&lt;br /&gt;
		checkSelf(self, 'width')&lt;br /&gt;
		checkType('fileLink:width', 1, px, 'number', true)&lt;br /&gt;
		if px and data.isUpright then&lt;br /&gt;
			sizeError('fileLink:width')&lt;br /&gt;
		end&lt;br /&gt;
		data.theWidth = px&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:height(px)&lt;br /&gt;
		checkSelf(self, 'height')&lt;br /&gt;
		checkType('fileLink:height', 1, px, 'number', true)&lt;br /&gt;
		if px and data.isUpright then&lt;br /&gt;
			sizeError('fileLink:height')&lt;br /&gt;
		end&lt;br /&gt;
		data.theHeight = px&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:upright(isUpright, factor)&lt;br /&gt;
		checkSelf(self, 'upright')&lt;br /&gt;
		checkType('fileLink:upright', 1, isUpright, 'boolean', true)&lt;br /&gt;
		checkType('fileLink:upright', 2, factor, 'number', true)&lt;br /&gt;
		if isUpright and (data.theWidth or data.theHeight) then&lt;br /&gt;
			sizeError('fileLink:upright')&lt;br /&gt;
		end&lt;br /&gt;
		data.isUpright = isUpright&lt;br /&gt;
		data.uprightFactor = factor&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:resetSize()&lt;br /&gt;
		checkSelf(self, 'resetSize')&lt;br /&gt;
		for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do&lt;br /&gt;
			data[field] = nil&lt;br /&gt;
		end&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:location(s)&lt;br /&gt;
		checkSelf(self, 'location')&lt;br /&gt;
		checkType('fileLink:location', 1, s, 'string', true)&lt;br /&gt;
		local validLocations = {&lt;br /&gt;
			right = true,&lt;br /&gt;
			left = true,&lt;br /&gt;
			center = true,&lt;br /&gt;
			none = true&lt;br /&gt;
		}&lt;br /&gt;
		if s == nil or validLocations[s] then&lt;br /&gt;
			data.theLocation = s&lt;br /&gt;
		else&lt;br /&gt;
			error(string.format(&lt;br /&gt;
				&amp;quot;bad argument #1 to 'fileLink:location' ('%s' is not a valid location)&amp;quot;,&lt;br /&gt;
				s&lt;br /&gt;
			), 2)&lt;br /&gt;
		end&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:alignment(s)&lt;br /&gt;
		checkSelf(self, 'alignment')&lt;br /&gt;
		checkType('fileLink:alignment', 1, s, 'string', true)&lt;br /&gt;
		local validAlignments = {&lt;br /&gt;
			baseline = true,&lt;br /&gt;
			middle = true,&lt;br /&gt;
			sub = true,&lt;br /&gt;
			super = true,&lt;br /&gt;
			['text-top'] = true,&lt;br /&gt;
			['text-bottom'] = true,&lt;br /&gt;
			top = true,&lt;br /&gt;
			bottom = true&lt;br /&gt;
		}&lt;br /&gt;
		if s == nil or validAlignments[s] then&lt;br /&gt;
			data.theAlignment = s&lt;br /&gt;
		else&lt;br /&gt;
			error(string.format(&lt;br /&gt;
				&amp;quot;bad argument #1 to 'fileLink:alignment' ('%s' is not a valid alignment)&amp;quot;,&lt;br /&gt;
				s&lt;br /&gt;
			), 2)&lt;br /&gt;
		end&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:border(hasBorder)&lt;br /&gt;
		checkSelf(self, 'border')&lt;br /&gt;
		checkType('fileLink:border', 1, hasBorder, 'boolean', true)&lt;br /&gt;
		data.hasBorder = hasBorder&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:link(s)&lt;br /&gt;
		checkSelf(self, 'link')&lt;br /&gt;
		checkType('fileLink:link', 1, s, 'string', true)&lt;br /&gt;
		data.theLink = s&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:alt(s)&lt;br /&gt;
		checkSelf(self, 'alt')&lt;br /&gt;
		checkType('fileLink:alt', 1, s, 'string', true)&lt;br /&gt;
		data.theAlt = s&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:page(num)&lt;br /&gt;
		checkSelf(self, 'page')&lt;br /&gt;
		checkType('fileLink:page', 1, num, 'number', true)&lt;br /&gt;
		data.thePage = s&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:class(s)&lt;br /&gt;
		checkSelf(self, 'class')&lt;br /&gt;
		checkType('fileLink:class', 1, s, 'string', true)&lt;br /&gt;
		data.theClass = s&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:lang(s)&lt;br /&gt;
		checkSelf(self, 'lang')&lt;br /&gt;
		checkType('fileLink:lang', 1, s, 'string', true)&lt;br /&gt;
		data.theLang = s&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function checkTypeStringOrNum(funcName, pos, arg)&lt;br /&gt;
		local argType = type(arg)&lt;br /&gt;
		if argType ~= 'nil' and argType ~= 'string' and argType ~= 'number' then&lt;br /&gt;
			error(string.format(&lt;br /&gt;
				&amp;quot;bad argument #%d to '%s' (string or number expected, got %s)&amp;quot;,&lt;br /&gt;
				pos,&lt;br /&gt;
				funcName,&lt;br /&gt;
				argType&lt;br /&gt;
			), 3)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:startTime(time)&lt;br /&gt;
		checkSelf(self, 'startTime')&lt;br /&gt;
		checkTypeStringOrNum('fileLink:startTime', 1, time)&lt;br /&gt;
		data.theStartTime = time&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:endTime(time)&lt;br /&gt;
		checkSelf(self, 'endTime')&lt;br /&gt;
		checkTypeStringOrNum('fileLink:endTime', 1, time)&lt;br /&gt;
		data.theEndTime = time&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:thumbTime(time)&lt;br /&gt;
		checkSelf(self, 'thumbTime')&lt;br /&gt;
		checkTypeStringOrNum('fileLink:thumbTime', 1, time)&lt;br /&gt;
		data.theThumbTime = time&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:caption(s)&lt;br /&gt;
		checkSelf(self, 'caption')&lt;br /&gt;
		checkType('fileLink:caption', 1, s, 'string', true)&lt;br /&gt;
		data.theCaption = s&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function data:render()&lt;br /&gt;
		checkSelf(self, 'render')&lt;br /&gt;
		local ret = {}&lt;br /&gt;
		&lt;br /&gt;
		-- Filename&lt;br /&gt;
		if not data.theName then&lt;br /&gt;
			error('fileLink:render: no filename was found')&lt;br /&gt;
		end&lt;br /&gt;
		ret[#ret + 1] = 'File:' .. data.theName&lt;br /&gt;
		&lt;br /&gt;
		-- Format&lt;br /&gt;
		if data.theFormat and data.theFormatFilename then&lt;br /&gt;
			ret[#ret + 1] = data.theFormat .. '=' .. data.theFormatFilename&lt;br /&gt;
		elseif data.theFormat then&lt;br /&gt;
			ret[#ret + 1] = data.theFormat&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Border&lt;br /&gt;
		if data.hasBorder then&lt;br /&gt;
			ret[#ret + 1] = 'border'&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Location&lt;br /&gt;
		ret[#ret + 1] = data.theLocation&lt;br /&gt;
&lt;br /&gt;
		-- Alignment&lt;br /&gt;
		ret[#ret + 1] = data.theAlignment&lt;br /&gt;
		&lt;br /&gt;
		-- Size&lt;br /&gt;
		if data.isUpright and data.uprightFactor then&lt;br /&gt;
			ret[#ret + 1] = 'upright=' .. tostring(data.uprightFactor)&lt;br /&gt;
		elseif data.isUpright then&lt;br /&gt;
			ret[#ret + 1] = 'upright'&lt;br /&gt;
		elseif data.theWidth and data.theHeight then&lt;br /&gt;
			ret[#ret + 1] = string.format('%dx%dpx', data.theWidth, data.theHeight)&lt;br /&gt;
		elseif data.theWidth then&lt;br /&gt;
			ret[#ret + 1] = tostring(data.theWidth) .. 'px'&lt;br /&gt;
		elseif data.theHeight then&lt;br /&gt;
			ret[#ret + 1] = string.format('x%dpx', data.theHeight)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Render named parameters.&lt;br /&gt;
		-- That includes link, alt, page, class, lang, start, end, and thumbtime.&lt;br /&gt;
		do&lt;br /&gt;
			local namedParameters = {&lt;br /&gt;
				{'link', 'theLink'},&lt;br /&gt;
				{'alt', 'theAlt'},&lt;br /&gt;
				{'page', 'thePage'},&lt;br /&gt;
				{'class', 'theClass'},&lt;br /&gt;
				{'lang', 'theLang'},&lt;br /&gt;
				{'start', 'theStartTime'},&lt;br /&gt;
				{'end', 'theEndTime'},&lt;br /&gt;
				{'thumbtime', 'theThumbTime'}&lt;br /&gt;
			}&lt;br /&gt;
			for i, t in ipairs(namedParameters) do&lt;br /&gt;
				local parameter = t[1]&lt;br /&gt;
				local value = data[t[2]]&lt;br /&gt;
				if value then&lt;br /&gt;
					ret[#ret + 1] = parameter .. '=' .. tostring(value)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Caption&lt;br /&gt;
		ret[#ret + 1] = data.theCaption&lt;br /&gt;
		&lt;br /&gt;
		return string.format('[[%s]]', table.concat(ret, '|'))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local privateFields = {&lt;br /&gt;
		theName = true,&lt;br /&gt;
		theFormat = true,&lt;br /&gt;
		theFormatFilename = true,&lt;br /&gt;
		theWidth = true,&lt;br /&gt;
		theHeight = true,&lt;br /&gt;
		isUpright = true,&lt;br /&gt;
		uprightFactor = true,&lt;br /&gt;
		theLocation = true,&lt;br /&gt;
		theAlignment = true,&lt;br /&gt;
		hasBorder = true,&lt;br /&gt;
		theLink = true,&lt;br /&gt;
		theAlt = true,&lt;br /&gt;
		thePage = true,&lt;br /&gt;
		theClass = true,&lt;br /&gt;
		theLang = true,&lt;br /&gt;
		theCaption = true&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	local readOnlyFields = {}&lt;br /&gt;
	for field in pairs(data) do&lt;br /&gt;
		readOnlyFields[field] = true&lt;br /&gt;
	end&lt;br /&gt;
	readOnlyFields.theName = nil -- This is set if a filename is given to fileLink.new, so remove it.&lt;br /&gt;
	&lt;br /&gt;
	local function restrictedFieldError(key, restriction)&lt;br /&gt;
		error(string.format(&lt;br /&gt;
			&amp;quot;fileLink object field '%s' is %s&amp;quot;,&lt;br /&gt;
			tostring(key),&lt;br /&gt;
			restriction&lt;br /&gt;
		), 3)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	setmetatable(obj, {&lt;br /&gt;
		__index = function (t, key)&lt;br /&gt;
			if privateFields[key] then&lt;br /&gt;
				restrictedFieldError(key, 'private')&lt;br /&gt;
			else&lt;br /&gt;
				return data[key]&lt;br /&gt;
			end&lt;br /&gt;
		end,&lt;br /&gt;
		__newindex = function (t, key, value)&lt;br /&gt;
			if privateFields[key] then&lt;br /&gt;
				restrictedFieldError(key, 'private')&lt;br /&gt;
			elseif readOnlyFields[key] then&lt;br /&gt;
				restrictedFieldError(key, 'read-only')&lt;br /&gt;
			else&lt;br /&gt;
				data[key] = value&lt;br /&gt;
			end&lt;br /&gt;
		end,&lt;br /&gt;
		__tostring = function (t)&lt;br /&gt;
			return t:render()&lt;br /&gt;
		end,&lt;br /&gt;
		__pairs = function ()&lt;br /&gt;
			local temp = {}&lt;br /&gt;
			for k, v in pairs(data) do&lt;br /&gt;
				if not privateFields[k] then&lt;br /&gt;
					temp[k] = v&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			return pairs(temp)&lt;br /&gt;
		end&lt;br /&gt;
	})&lt;br /&gt;
	&lt;br /&gt;
	return obj&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return fileLink&lt;/div&gt;</summary>
		<author><name>Shawndouglas</name></author>
	</entry>
</feed>