Module:File parse
Appearance
| This module is rated as alpha. It is ready for limited use and third-party feedback. It may be used on a small number of pages, but should be monitored closely. Suggestions for new features or adjustments to input and output are welcome. |
Usage
[edit]{{#invoke:File parse | parse | {{{file}}} | {{{output}}} }}
When a file is passed, output a requested piece of information which was extracted from it.
Parameters
[edit]{{{file}}}
[edit]File in the syntax documented at Wikipedia:Extended image syntax.
{{{output}}}
[edit]One of: name,type,border,location,alignment,size,link,alt,page,lang,caption
local p = {};
local function split_pipes(s)
local tokens = {}
local buf = {}
local depth_link, depth_tpl = 0, 0
local i = 1
while i <= #s do
local two = s:sub(i,i+1)
if two == "[[" then
depth_link = depth_link + 1
table.insert(buf, two)
i = i + 2
elseif two == "]]" and depth_link > 0 then
depth_link = depth_link - 1
table.insert(buf, two)
i = i + 2
elseif two == "{{" then
depth_tpl = depth_tpl + 1
table.insert(buf, two)
i = i + 2
elseif two == "}}" and depth_tpl > 0 then
depth_tpl = depth_tpl - 1
table.insert(buf, two)
i = i + 2
elseif s:sub(i,i) == "|" and depth_link == 0 and depth_tpl == 0 then
-- split here
table.insert(tokens, mw.text.trim(table.concat(buf)))
buf = {}
i = i + 1
else
table.insert(buf, s:sub(i,i))
i = i + 1
end
end
if #buf > 0 then
table.insert(tokens, mw.text.trim(table.concat(buf)))
end
return tokens
end
function p.parse(frame)
local s = frame.args[1]
local key = frame.args[2]
s = mw.text.trim(s)
-- Strip outer [[ ]] if present
if s:match("^%[%[.*%]%]$") then
s = s:sub(3, -3) -- from 3rd char to 3rd-from-last char
s = mw.text.trim(s)
end
-- Must start with File: or Image:
local prefix, rest = s:match("^(File:)(.+)$")
if not rest then
prefix, rest = s:match("^(Image:)(.+)$")
end
if not rest then
return nil, "Not a File/Image wikilink"
end
rest = mw.text.trim(rest)
local tokens = split_pipes(rest)
local name = table.remove(tokens, 1)
local res = {
raw = "[[" .. prefix .. rest .. "]]",
name = name,
type = nil,
border = false,
location = nil,
alignment = nil,
size = nil,
link = nil,
alt = nil,
page = nil,
lang = nil,
other = {},
caption = nil,
}
-- parse options
for i, tok in ipairs(tokens) do
local lowered = tok:lower()
if lowered == "thumb" or lowered == "thumbnail" or lowered == "frame"
or lowered == "framed" or lowered == "frameless" then
res.type = lowered
elseif lowered == "border" then
res.border = true
elseif lowered == "right" or lowered == "left" or lowered == "center" or lowered == "none" then
res.location = lowered
elseif lowered:match("^upright") then
local factor = lowered:match("^upright=([0-9%.]+)$")
res.size = { upright = tonumber(factor) or 1 }
elseif lowered:match("^([0-9]+)px$") then
res.size = { width = tonumber(lowered:match("^(%d+)px$")), px = true }
elseif lowered:match("^x([0-9]+)px$") then
res.size = { height = tonumber(lowered:match("^x(%d+)px$")), px = true }
elseif lowered:match("^([0-9]+)x([0-9]+)px$") then
local w,h = lowered:match("^(%d+)x(%d+)px$")
res.size = { width = tonumber(w), height = tonumber(h), px = true }
elseif lowered:match("^alt=") then
res.alt = tok:match("^alt=(.+)$")
elseif lowered:match("^link=") then
res.link = tok:match("^link=(.+)$")
elseif lowered:match("^page=") then
res.page = tonumber(tok:match("^page=(%d+)$"))
elseif lowered:match("^lang=") then
res.lang = tok:match("^lang=(.+)$")
else
-- assume caption if it's last, otherwise shove into "other"
if i == #tokens then
res.caption = tok
else
res.other[#res.other+1] = tok
end
end
end
if key then
return res[key]
else
return res
end
end
return p;