Editing Module:File link

From MINR.ORG WIKI

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
 
-- This module provides a library for formatting file wikilinks.
 
-- This module provides a library for formatting file wikilinks.
  
local yesno = require('Module:Yesno')
+
local libraryUtil = require('libraryUtil')
local checkType = require('libraryUtil').checkType
+
local checkType = libraryUtil.checkType
  
local p = {}
+
local fileLink = {}
  
function p._main(args)
+
function fileLink.new(filename)
checkType('_main', 1, args, 'table')
+
checkType('fileLink.new', 1, filename, 'string', true)
 
+
local obj, data = {}, {}
-- This is basically libraryUtil.checkTypeForNamedArg, but we are rolling our
+
-- own function to get the right error level.
+
local checkSelf = libraryUtil.makeCheckSelfFunction(
local function checkArg(key, val, level)
+
'fileLink',
if type(val) ~= 'string' then
+
'fileLink',
 +
obj,
 +
'fileLink object'
 +
)
 +
 +
-- Set the filename if we were passed it as an input to fileLink.new.
 +
if filename then
 +
data.theName = filename
 +
end
 +
 +
function data:name(s)
 +
checkSelf(self, 'name')
 +
checkType('fileLink:name', 1, s, 'string')
 +
data.theName = s
 +
return self
 +
end
 +
 +
function data:format(s, filename)
 +
checkSelf(self, 'format')
 +
checkType('fileLink:format', 1, s, 'string', true)
 +
checkType('fileLink:format', 2, format, 'string', true)
 +
local validFormats = {
 +
thumb = true,
 +
thumbnail = true,
 +
frame = true,
 +
framed = true,
 +
frameless = true
 +
}
 +
if s == nil or validFormats[s] then
 +
data.theFormat = s
 +
data.theFormatFilename = filename
 +
else
 
error(string.format(
 
error(string.format(
"type error in '%s' parameter of '_main' (expected string, got %s)",
+
"bad argument #1 to 'fileLink:format' ('%s' is not a valid format)",
key, type(val)
+
s
), level)
+
), 2)
 
end
 
end
 +
return self
 
end
 
end
  
local ret = {}
+
local function sizeError(methodName)
 
+
-- Used for formatting duplication errors in size-related methods.
-- Adds a positional parameter to the buffer.
+
error(string.format(
local function addPositional(key)
+
"duplicate size argument detected in '%s'"
local val = args[key]
+
.. " ('upright' cannot be used in conjunction with height or width)",
if not val then
+
methodName
return nil
+
), 3)
 +
end
 +
 +
function data:width(px)
 +
checkSelf(self, 'width')
 +
checkType('fileLink:width', 1, px, 'number', true)
 +
if px and data.isUpright then
 +
sizeError('fileLink:width')
 +
end
 +
data.theWidth = px
 +
return self
 +
end
 +
 +
function data:height(px)
 +
checkSelf(self, 'height')
 +
checkType('fileLink:height', 1, px, 'number', true)
 +
if px and data.isUpright then
 +
sizeError('fileLink:height')
 +
end
 +
data.theHeight = px
 +
return self
 +
end
 +
 +
function data:upright(isUpright, factor)
 +
checkSelf(self, 'upright')
 +
checkType('fileLink:upright', 1, isUpright, 'boolean', true)
 +
checkType('fileLink:upright', 2, factor, 'number', true)
 +
if isUpright and (data.theWidth or data.theHeight) then
 +
sizeError('fileLink:upright')
 +
end
 +
data.isUpright = isUpright
 +
data.uprightFactor = factor
 +
return self
 +
end
 +
 +
function data:resetSize()
 +
checkSelf(self, 'resetSize')
 +
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do
 +
data[field] = nil
 
end
 
end
checkArg(key, val, 4)
+
return self
ret[#ret + 1] = val
 
 
end
 
end
 
+
-- Adds a named parameter to the buffer. We assume that the parameter name
+
function data:location(s)
-- is the same as the argument key.
+
checkSelf(self, 'location')
local function addNamed(key)
+
checkType('fileLink:location', 1, s, 'string', true)
local val = args[key]
+
local validLocations = {
if not val then
+
right = true,
return nil
+
left = true,
 +
center = true,
 +
none = true
 +
}
 +
if s == nil or validLocations[s] then
 +
data.theLocation = s
 +
else
 +
error(string.format(
 +
"bad argument #1 to 'fileLink:location' ('%s' is not a valid location)",
 +
s
 +
), 2)
 
end
 
end
checkArg(key, val, 4)
+
return self
ret[#ret + 1] = key .. '=' .. val
 
 
end
 
end
 
+
-- Filename
+
function data:alignment(s)
checkArg('file', args.file, 3)
+
checkSelf(self, 'alignment')
ret[#ret + 1] = 'File:' .. args.file
+
checkType('fileLink:alignment', 1, s, 'string', true)
 
+
local validAlignments = {
-- Format
+
baseline = true,
if args.format then
+
middle = true,
checkArg('format', args.format)
+
sub = true,
if args.formatfile then
+
super = true,
checkArg('formatfile', args.formatfile)
+
['text-top'] = true,
ret[#ret + 1] = args.format .. '=' .. args.formatfile
+
['text-bottom'] = true,
 +
top = true,
 +
bottom = true
 +
}
 +
if s == nil or validAlignments[s] then
 +
data.theAlignment = s
 
else
 
else
ret[#ret + 1] = args.format
+
error(string.format(
 +
"bad argument #1 to 'fileLink:alignment' ('%s' is not a valid alignment)",
 +
s
 +
), 2)
 
end
 
end
 +
return self
 +
end
 +
 +
function data:border(hasBorder)
 +
checkSelf(self, 'border')
 +
checkType('fileLink:border', 1, hasBorder, 'boolean', true)
 +
data.hasBorder = hasBorder
 +
return self
 +
end
 +
 +
function data:link(s)
 +
checkSelf(self, 'link')
 +
checkType('fileLink:link', 1, s, 'string', true)
 +
data.theLink = s
 +
return self
 +
end
 +
 +
function data:alt(s)
 +
checkSelf(self, 'alt')
 +
checkType('fileLink:alt', 1, s, 'string', true)
 +
data.theAlt = s
 +
return self
 +
end
 +
 +
function data:page(num)
 +
checkSelf(self, 'page')
 +
checkType('fileLink:page', 1, num, 'number', true)
 +
data.thePage = s
 +
return self
 +
end
 +
 +
function data:class(s)
 +
checkSelf(self, 'class')
 +
checkType('fileLink:class', 1, s, 'string', true)
 +
data.theClass = s
 +
return self
 +
end
 +
 +
function data:lang(s)
 +
checkSelf(self, 'lang')
 +
checkType('fileLink:lang', 1, s, 'string', true)
 +
data.theLang = s
 +
return self
 
end
 
end
  
-- Border
+
local function checkTypeStringOrNum(funcName, pos, arg)
if yesno(args.border) then
+
local argType = type(arg)
ret[#ret + 1] = 'border'
+
if argType ~= 'nil' and argType ~= 'string' and argType ~= 'number' then
 +
error(string.format(
 +
"bad argument #%d to '%s' (string or number expected, got %s)",
 +
pos,
 +
funcName,
 +
argType
 +
), 3)
 +
end
 
end
 
end
 +
 +
function data:startTime(time)
 +
checkSelf(self, 'startTime')
 +
checkTypeStringOrNum('fileLink:startTime', 1, time)
 +
data.theStartTime = time
 +
return self
 +
end
 +
 +
function data:endTime(time)
 +
checkSelf(self, 'endTime')
 +
checkTypeStringOrNum('fileLink:endTime', 1, time)
 +
data.theEndTime = time
 +
return self
 +
end
 +
 +
function data:thumbTime(time)
 +
checkSelf(self, 'thumbTime')
 +
checkTypeStringOrNum('fileLink:thumbTime', 1, time)
 +
data.theThumbTime = time
 +
return self
 +
end
 +
 +
function data:caption(s)
 +
checkSelf(self, 'caption')
 +
checkType('fileLink:caption', 1, s, 'string', true)
 +
data.theCaption = s
 +
return self
 +
end
 +
 +
function data:render()
 +
checkSelf(self, 'render')
 +
local ret = {}
 +
 +
-- Filename
 +
if not data.theName then
 +
error('fileLink:render: no filename was found')
 +
end
 +
ret[#ret + 1] = 'File:' .. data.theName
 +
 +
-- Format
 +
if data.theFormat and data.theFormatFilename then
 +
ret[#ret + 1] = data.theFormat .. '=' .. data.theFormatFilename
 +
elseif data.theFormat then
 +
ret[#ret + 1] = data.theFormat
 +
end
 +
 +
-- Border
 +
if data.hasBorder then
 +
ret[#ret + 1] = 'border'
 +
end
 +
 +
-- Location
 +
ret[#ret + 1] = data.theLocation
  
addPositional('location')
+
-- Alignment
addPositional('alignment')
+
ret[#ret + 1] = data.theAlignment
addPositional('size')
+
addNamed('upright')
+
-- Size
addNamed('link')
+
if data.isUpright and data.uprightFactor then
addNamed('alt')
+
ret[#ret + 1] = 'upright=' .. tostring(data.uprightFactor)
addNamed('page')
+
elseif data.isUpright then
addNamed('class')
+
ret[#ret + 1] = 'upright'
addNamed('lang')
+
elseif data.theWidth and data.theHeight then
addNamed('start')
+
ret[#ret + 1] = string.format('%dx%dpx', data.theWidth, data.theHeight)
addNamed('end')
+
elseif data.theWidth then
addNamed('thumbtime')
+
ret[#ret + 1] = tostring(data.theWidth) .. 'px'
addPositional('caption')
+
elseif data.theHeight then
 +
ret[#ret + 1] = string.format('x%dpx', data.theHeight)
 +
end
 +
 +
-- Render named parameters.
 +
-- That includes link, alt, page, class, lang, start, end, and thumbtime.
 +
do
 +
local namedParameters = {
 +
{'link', 'theLink'},
 +
{'alt', 'theAlt'},
 +
{'page', 'thePage'},
 +
{'class', 'theClass'},
 +
{'lang', 'theLang'},
 +
{'start', 'theStartTime'},
 +
{'end', 'theEndTime'},
 +
{'thumbtime', 'theThumbTime'}
 +
}
 +
for i, t in ipairs(namedParameters) do
 +
local parameter = t[1]
 +
local value = data[t[2]]
 +
if value then
 +
ret[#ret + 1] = parameter .. '=' .. tostring(value)
 +
end
 +
end
 +
end
  
return string.format('[[%s]]', table.concat(ret, '|'))
+
-- Caption
end
+
ret[#ret + 1] = data.theCaption
 
+
function p.main(frame)
+
return string.format('[[%s]]', table.concat(ret, '|'))
local origArgs = require('Module:Arguments').getArgs(frame, {
+
end
wrappers = 'Template:File link'
+
})
+
local privateFields = {
if not origArgs.file then
+
theName = true,
error("'file' parameter missing from [[Template:File link]]", 0)
+
theFormat = true,
 +
theFormatFilename = true,
 +
theWidth = true,
 +
theHeight = true,
 +
isUpright = true,
 +
uprightFactor = true,
 +
theLocation = true,
 +
theAlignment = true,
 +
hasBorder = true,
 +
theLink = true,
 +
theAlt = true,
 +
thePage = true,
 +
theClass = true,
 +
theLang = true,
 +
theCaption = true
 +
}
 +
 +
local readOnlyFields = {}
 +
for field in pairs(data) do
 +
readOnlyFields[field] = true
 +
end
 +
readOnlyFields.theName = nil -- This is set if a filename is given to fileLink.new, so remove it.
 +
 +
local function restrictedFieldError(key, restriction)
 +
error(string.format(
 +
"fileLink object field '%s' is %s",
 +
tostring(key),
 +
restriction
 +
), 3)
 
end
 
end
 
+
-- Copy the arguments that were passed to a new table to avoid looking up
+
setmetatable(obj, {
-- every possible parameter in the frame object.
+
__index = function (t, key)
local args = {}
+
if privateFields[key] then
for k, v in pairs(origArgs) do
+
restrictedFieldError(key, 'private')
-- Make _BLANK a special argument to add a blank parameter. For use in
+
else
-- conditional templates etc. it is useful for blank arguments to be
+
return data[key]
-- ignored, but we still need a way to specify them so that we can do
+
end
-- things like [[File:Example.png|link=]].
+
end,
if v == '_BLANK' then
+
__newindex = function (t, key, value)
v = ''
+
if privateFields[key] then
 +
restrictedFieldError(key, 'private')
 +
elseif readOnlyFields[key] then
 +
restrictedFieldError(key, 'read-only')
 +
else
 +
data[key] = value
 +
end
 +
end,
 +
__tostring = function (t)
 +
return t:render()
 +
end,
 +
__pairs = function ()
 +
local temp = {}
 +
for k, v in pairs(data) do
 +
if not privateFields[k] then
 +
temp[k] = v
 +
end
 +
end
 +
return pairs(temp)
 
end
 
end
args[k] = v
+
})
end
+
return p._main(args)
+
return obj
 
end
 
end
  
return p
+
return fileLink

Please note that all contributions to MINR.ORG WIKI may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see MINR.ORG WIKI:Copyrights for details). Do not submit copyrighted work without permission!

Cancel Editing help (opens in new window)