Module:File link: Difference between revisions
imported>Mr. Stradivarius (beginnings of an image library) |
imported>Mr. Stradivarius (add type checks and write the render function; read-only code not working yet) |
||
Line 1: | Line 1: | ||
-- This module provides a library for formatting image wikilinks. |
|||
local libraryUtil = require('libraryUtil') |
|||
local image = {} |
local image = {} |
||
function image.new() |
function image.new() |
||
local obj, data = {}, {} |
local obj, data = {}, {} |
||
local checkSelf = libraryUtil.makeCheckSelfFunction('image', 'image', obj, 'image object') |
|||
local checkType = libraryUtil.checkType |
|||
function data:name(s) |
function data:name(s) |
||
checkSelf(self, 'name') |
|||
checkType('name', 1, s, 'string') |
|||
self.theName = s |
self.theName = s |
||
end |
end |
||
function data:format(s, filename) |
function data:format(s, filename) |
||
checkSelf(self, 'format') |
|||
checkType('format', 1, s, 'string') |
|||
checkType('format', 2, format, 'string', true) |
|||
local validFormats = { |
local validFormats = { |
||
thumb = true, |
thumb = true, |
||
Line 25: | Line 37: | ||
function data:width(px) |
function data:width(px) |
||
checkSelf(self, 'width') |
|||
checkType('width', 1, px, 'number') |
|||
self.theWidth = px |
self.theWidth = px |
||
end |
end |
||
function data:height(px) |
function data:height(px) |
||
checkSelf(self, 'height') |
|||
checkType('height', 1, px, 'number') |
|||
self.theHeight = px |
self.theHeight = px |
||
end |
end |
||
function data:upright(factor) |
function data:upright(factor) |
||
checkSelf(self, 'upright') |
|||
checkType('upright', 1, factor, 'number', true) |
|||
self.isUpright = true |
self.isUpright = true |
||
self.uprightFactor = factor |
self.uprightFactor = factor |
||
Line 38: | Line 56: | ||
function data:resetSize() |
function data:resetSize() |
||
checkSelf(self, 'resetSize') |
|||
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do |
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do |
||
self[field] = nil |
self[field] = nil |
||
Line 44: | Line 63: | ||
function data:location(s) |
function data:location(s) |
||
checkSelf(self, 'location') |
|||
checkType('location', 1, s, 'string') |
|||
local validLocations = { |
local validLocations = { |
||
right = true, |
right = true, |
||
Line 50: | Line 71: | ||
none = true |
none = true |
||
} |
} |
||
if |
if validLocations[s] then |
||
self.theLocation = s |
self.theLocation = s |
||
else |
else |
||
error(string.format( |
error(string.format( |
||
"bad argument #1 to 'image:location'" |
"bad argument #1 to 'image:location' ('%s' is not a valid location)", |
||
s |
|||
.. " (must be one of 'right', 'left', 'center' or 'none'; got '%s').", |
|||
tostring(s) |
|||
)) |
)) |
||
end |
end |
||
Line 62: | Line 82: | ||
function data:alignment(s) |
function data:alignment(s) |
||
checkSelf(self, 'alignment') |
|||
checkType('alignment', 1, s, 'string') |
|||
local validAlignments = { |
local validAlignments = { |
||
baseline = true, |
baseline = true, |
||
Line 72: | Line 94: | ||
bottom = true |
bottom = true |
||
} |
} |
||
if |
if validAlignments[s] then |
||
self.theAlignment = s |
self.theAlignment = s |
||
else |
else |
||
error(string.format( |
error(string.format( |
||
"bad argument #1 to ' |
"bad argument #1 to 'image:alignment' ('%s' is not a valid alignment)" |
||
)) |
)) |
||
end |
end |
||
Line 82: | Line 104: | ||
function data:border() |
function data:border() |
||
checkSelf(self, 'border') |
|||
self.hasBorder = true |
self.hasBorder = true |
||
end |
end |
||
function data:link(s) |
function data:link(s) |
||
checkSelf(self, 'link') |
|||
checkType('link', 1, s, 'string') |
|||
self.theLink = s |
self.theLink = s |
||
end |
end |
||
function data:alt(s) |
function data:alt(s) |
||
checkSelf(self, 'alt') |
|||
checkType('alt', 1, s, 'string') |
|||
self.theAlt = s |
self.theAlt = s |
||
end |
end |
||
function data:caption(s) |
function data:caption(s) |
||
checkSelf(self, 'caption') |
|||
checkType('caption', 1, s, 'string') |
|||
self.theCaption = s |
self.theCaption = s |
||
end |
end |
||
function data:render() |
function data:render() |
||
checkSelf(self, 'render') |
|||
local ret = {} |
|||
-- Image name. |
|||
if not self.theName then |
|||
error('image:render: no image name was found') |
|||
end |
|||
ret[#ret + 1] = 'File:' .. self.theName |
|||
-- Image format |
|||
if self.theFormat and self.theFormatFilename then |
|||
ret[#ret + 1] = self.theFormat .. '=' .. self.theFormatFilename |
|||
elseif self.theFormat then |
|||
ret[#ret + 1] = self.theFormat |
|||
end |
|||
-- Border |
|||
if self.hasBorder then |
|||
ret[#ret + 1] = 'border' |
|||
end |
|||
-- Location |
|||
ret[#ret + 1] = self.theLocation |
|||
-- Alignment |
|||
ret[#ret + 1] = self.theAlignment |
|||
-- Size |
|||
if self.isUpright and (self.theWidth or self.theHeight) then |
|||
error("duplicate size value detected in 'render' (height/width cannot be used at the same time as 'upright')") |
|||
elseif self.isUpright and self.uprightFactor then |
|||
ret[#ret + 1] = 'upright=' .. tostring(self.uprightFactor) |
|||
elseif self.isUpright then |
|||
ret[#ret + 1] = 'upright' |
|||
elseif self.theWidth and self.theHeight then |
|||
ret[#ret + 1] = string.format('%dx%dpx', self.theWidth, self.theHeight) |
|||
elseif self.theWidth then |
|||
ret[#ret + 1] = tostring(self.theWidth) .. 'px' |
|||
elseif self.theHeight then |
|||
ret[#ret + 1] = string.format('x%dpx', self.theHeight) |
|||
end |
|||
-- Link |
|||
if self.theLink then |
|||
ret[#ret + 1] = 'link=' .. self.theLink |
|||
end |
|||
-- Alt |
|||
if self.theAlt then |
|||
ret[#ret + 1] = 'alt=' .. self.theAlt |
|||
end |
|||
-- Caption |
|||
ret[#ret + 1] = self.theCaption |
|||
return string.format('[[%s]]', table.concat(ret, '|')) |
|||
end |
end |
||
local readOnlyFields = { |
|||
theName = true, |
|||
theFormat = true, |
|||
theFormatFilename = true, |
|||
theWidth = true, |
|||
theHeight = true, |
|||
isUpright = true, |
|||
uprightFactor = true, |
|||
theLocation = true, |
|||
theAlignment = true, |
|||
hasBorder = true, |
|||
theLink = true, |
|||
theAlt = true, |
|||
theCaption = true |
|||
} |
|||
for field in pairs(data) do |
|||
readOnlyFields[field] = true |
|||
end |
|||
setmetatable(obj, { |
|||
__index = data, |
|||
__newindex = function (t, key, value) |
|||
if readOnlyFields[key] then |
|||
error(string.format( |
|||
"field '%s' is read-only", |
|||
tostring(key) |
|||
), 2) |
|||
else |
|||
data[key] = value |
|||
end |
|||
end, |
|||
__tostring = function (t) |
|||
return t:render() |
|||
end |
|||
}) |
|||
return obj |
return obj |
||
end |
end |
||
return image |
-- return image |
||
local p = {} |
|||
function p.test() |
|||
local myImage = image.new() |
|||
myImage:name('Foo') |
|||
return myImage:render() |
|||
end |
|||
return p |
Revision as of 01:49, 30 May 2014
![]() | This Lua module is used on approximately 76,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This module depends on the following other modules: |
This module is used to construct wikitext links to files. It is primarily useful for templates and modules that use complicated logic to make file links. Simple file links should be made with wikitext markup directly, as it uses less resources than calling this module. For help with wikitext file markup please refer to the documentation at mediawiki.org.
Usage from wikitext
From wikitext, this module should be called from a template, usually {{file link}}. Please see the template page for documentation. However, it can also be called using the syntax {{#invoke:File link|main|arguments}}
.
Usage from Lua
First, you need to import the module.
local mFileLink = require('Module:File link')
Then you can make file links using the _main
function.
mFileLink._main(args)
args is a table of arguments that can have the following keys:
file
- the filename. (required)format
- the file format, e.g. 'thumb', 'thumbnail', 'frame', 'framed', or 'frameless'.formatfile
- a filename to specify with the 'thumbnail' format option. The filename specified will be used instead of the automatically generated thumbnail.border
- set this to true or "yes" (or any other value recognized as true by Module:Yesno) to set a border for the image.location
- the horizontal alignment of the file, e.g. 'right', 'left', 'center', or 'none'.alignment
- the vertical alignment of the file, e.g. 'baseline', 'middle', 'sub', 'super', 'text-top', 'text-bottom', 'top', or 'bottom'.size
- the size of the image, e.g. '100px', 'x100px' or '100x100px'.upright
- the 'upright' parameter, used for setting the size of tall and thin images.link
- the page that the file should link to. Use the blank string '' to suppress the default link to the file description page.alt
- the alt text. Use the blank string '' to suppress the default alt text.caption
- a caption for the file.page
- sets a page number for multi-paged files such as PDFs.class
- adds aclass
parameter to image links. The MediaWiki software adds this parameter to theclass="..."
attribute of the image's<img />
element when the page is rendered into HTML.lang
- adds a language attribute to specify what language to render the file in.start
- specifies a start time for audio and video files.end
- specifies an end time for audio and video files.thumbtime
- specifies the time to use to generate the thumbnail image for video files.
To see the effect of each of these parameters, see the images help page on mediawiki.org.
Examples
With the file only:
mFileLink.main{file = 'Example.png'}
-- Renders as [[File:Example.png]]
With format, size, link and caption options:
mFileLink.main{
file = 'Example.png',
format = 'thumb',
size = '220px',
link = 'Wikipedia:Sandbox',
caption = 'An example.'
}
-- Renders as [[File:Example.png|thumb|220px|link=Wikipedia:Sandbox|An example.]]
With format, size, and border:
mFileLink.main{
file = 'Example.png',
format = 'frameless',
size = '220px',
border = true
}
-- Renders as [[File:Example.png|frameless|border|220px]]
-- This module provides a library for formatting image wikilinks.
local libraryUtil = require('libraryUtil')
local image = {}
function image.new()
local obj, data = {}, {}
local checkSelf = libraryUtil.makeCheckSelfFunction('image', 'image', obj, 'image object')
local checkType = libraryUtil.checkType
function data:name(s)
checkSelf(self, 'name')
checkType('name', 1, s, 'string')
self.theName = s
end
function data:format(s, filename)
checkSelf(self, 'format')
checkType('format', 1, s, 'string')
checkType('format', 2, format, 'string', true)
local validFormats = {
thumb = true,
thumbnail = true,
frame = true,
framed = true,
frameless = true
}
if validFormats[s] then
self.theFormat = s
self.theFormatFilename = filename
else
error('invalid format')
end
end
function data:width(px)
checkSelf(self, 'width')
checkType('width', 1, px, 'number')
self.theWidth = px
end
function data:height(px)
checkSelf(self, 'height')
checkType('height', 1, px, 'number')
self.theHeight = px
end
function data:upright(factor)
checkSelf(self, 'upright')
checkType('upright', 1, factor, 'number', true)
self.isUpright = true
self.uprightFactor = factor
end
function data:resetSize()
checkSelf(self, 'resetSize')
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do
self[field] = nil
end
end
function data:location(s)
checkSelf(self, 'location')
checkType('location', 1, s, 'string')
local validLocations = {
right = true,
left = true,
center = true,
none = true
}
if validLocations[s] then
self.theLocation = s
else
error(string.format(
"bad argument #1 to 'image:location' ('%s' is not a valid location)",
s
))
end
end
function data:alignment(s)
checkSelf(self, 'alignment')
checkType('alignment', 1, s, 'string')
local validAlignments = {
baseline = true,
middle = true,
sub = true,
super = true,
['text-top'] = true,
['text-bottom'] = true,
top = true,
bottom = true
}
if validAlignments[s] then
self.theAlignment = s
else
error(string.format(
"bad argument #1 to 'image:alignment' ('%s' is not a valid alignment)"
))
end
end
function data:border()
checkSelf(self, 'border')
self.hasBorder = true
end
function data:link(s)
checkSelf(self, 'link')
checkType('link', 1, s, 'string')
self.theLink = s
end
function data:alt(s)
checkSelf(self, 'alt')
checkType('alt', 1, s, 'string')
self.theAlt = s
end
function data:caption(s)
checkSelf(self, 'caption')
checkType('caption', 1, s, 'string')
self.theCaption = s
end
function data:render()
checkSelf(self, 'render')
local ret = {}
-- Image name.
if not self.theName then
error('image:render: no image name was found')
end
ret[#ret + 1] = 'File:' .. self.theName
-- Image format
if self.theFormat and self.theFormatFilename then
ret[#ret + 1] = self.theFormat .. '=' .. self.theFormatFilename
elseif self.theFormat then
ret[#ret + 1] = self.theFormat
end
-- Border
if self.hasBorder then
ret[#ret + 1] = 'border'
end
-- Location
ret[#ret + 1] = self.theLocation
-- Alignment
ret[#ret + 1] = self.theAlignment
-- Size
if self.isUpright and (self.theWidth or self.theHeight) then
error("duplicate size value detected in 'render' (height/width cannot be used at the same time as 'upright')")
elseif self.isUpright and self.uprightFactor then
ret[#ret + 1] = 'upright=' .. tostring(self.uprightFactor)
elseif self.isUpright then
ret[#ret + 1] = 'upright'
elseif self.theWidth and self.theHeight then
ret[#ret + 1] = string.format('%dx%dpx', self.theWidth, self.theHeight)
elseif self.theWidth then
ret[#ret + 1] = tostring(self.theWidth) .. 'px'
elseif self.theHeight then
ret[#ret + 1] = string.format('x%dpx', self.theHeight)
end
-- Link
if self.theLink then
ret[#ret + 1] = 'link=' .. self.theLink
end
-- Alt
if self.theAlt then
ret[#ret + 1] = 'alt=' .. self.theAlt
end
-- Caption
ret[#ret + 1] = self.theCaption
return string.format('[[%s]]', table.concat(ret, '|'))
end
local readOnlyFields = {
theName = true,
theFormat = true,
theFormatFilename = true,
theWidth = true,
theHeight = true,
isUpright = true,
uprightFactor = true,
theLocation = true,
theAlignment = true,
hasBorder = true,
theLink = true,
theAlt = true,
theCaption = true
}
for field in pairs(data) do
readOnlyFields[field] = true
end
setmetatable(obj, {
__index = data,
__newindex = function (t, key, value)
if readOnlyFields[key] then
error(string.format(
"field '%s' is read-only",
tostring(key)
), 2)
else
data[key] = value
end
end,
__tostring = function (t)
return t:render()
end
})
return obj
end
-- return image
local p = {}
function p.test()
local myImage = image.new()
myImage:name('Foo')
return myImage:render()
end
return p