Module:FileParse

-- local p = {} -- stuff to work with -- format local fmt = {'border', 'frame', 'frameless', 'thumb', 'thumbnail'} -- resize local resize = {'^%d+px$', '^x%d+px$', '^%d+x%d+$', '^%d+x%d+px$', '^upright$'} -- horizontal align local hor = {'left', 'right', 'center', 'none'} -- vertical align local ver = {'baseline', 'sub', 'super' ,'top', 'text-top', 'middle', 'bottom', 'text-bottom'} -- supposed to be regex params, but were fired in favor to text.split local reparams = {['link'] = '^link.*', ['alt'] = '^alt=.*', ['page'] = '^page=.*', ['class'] = '^class=.*', ['lang'] = '^lang=.*'}

function p.file(frame, source) -- parse file:x for params -- source (or frame.args.1): -- returns file table: name: filename. nil if the source not recognized as proper file link fmt: table of formats: 'border', 'frame', 'frameless', 'thumb', 'thumbnail' resize: new size hor: horizontal align ver: vertical align alt, page, class, lang, link: corresponding params stuff, caption: inrecognized params, that supposed to be a caption :toString returns string dump (all the stuff, except ); note: reformatted (due to pairs nature) frame = frame or {} local args = frame.args or frame local debug = args.debug or false local a1 = source or args['1'] or args[1] or '' -- file object local file = {toString = toString} -- check for file: local localFile = mw.site.namespaces[6].name -- en pattern local enFile = '%[%[[Ff]ile:.*%]%]'   -- localized pattern    localFile = '[' .. mw.ustring.sub(localFile, 1, 1) .. mw.ustring.lower(mw.ustring.sub(localFile, 1, 1)) .. ']' .. mw.ustring.sub(localFile, 2) .. ':.*%]%]'    if not (mw.ustring.match(a1, enFile) or mw.ustring.match(a1, localFile)) then        if debug then            return 'not a file: ' .. a1        end        return file    end    -- get source data    local src = mw.ustring.gsub(a1, '%[%[%w+:(.-)%]%]', '%1')    -- params     local arr = mw.text.split(src, '|')    -- temp vars    local s1, breaker    -- name is always 1st    file.name = arr[1]    -- don't process the name    table.remove(arr, 1)    for i = #arr, 1, -1 do        breaker = false        -- format        for k = #fmt, 1, -1 do            if arr[i] == fmt[k] then                -- multiple values allowed: https://www.mediawiki.org/wiki/Help:Images                file.fmt = file.fmt or {}                table.insert(file.fmt, arr[i])                -- avoid duplication                table.remove(fmt, k)                table.remove(arr, i)                breaker = true                break            end        end-- format        -- resize        if not breaker and not file.resize then            for k = #resize, 1, -1 do                s1 = mw.ustring.match(arr[i], resize[k])                if s1 then                    file.resize = s1                    table.remove(arr, i)                    breaker = true                    break                end            end        end-- resize        --hor        if not breaker and not file.hor then            for k = #hor, 1, -1 do                if arr[i] == hor[k] then                    file.hor = hor[k]                    table.remove(arr, i)                    breaker = true                    break                end            end        end-- hor        --ver        if not breaker and not file.ver then            for k = #ver, 1, -1 do                if arr[i] == ver[k] then                    file.ver = ver[k]                    table.remove(arr, i)                    breaker = true                    break                end            end        end-- ver        -- reparams        if not breaker then            for k, v in pairs(reparams) do                s1 = mw.text.split(arr[i], k .. '=', true)                if s1[2] ~= nil then                    file[k] = s1[2]                    table.remove(arr, i)                    breaker = true                    break                end            end        end-- reparams    end-- for i in arr    -- stuff. all not recognized stuff    local stuff = table.concat(arr, '|')    file.stuff = stuff    -- more appropriate name    file.caption = stuff    if debug then        return 'ret:', file, ' src:', src, ' tostring:', frame.preprocess and frame:preprocess(' ' .. file:toString('|') .. ' ') or file:toString, ' name:', file.name, ' format:', tableConcat(file.fmt, '|'), ' resize:', file.resize or , ' stuff:', file.stuff or , ' hor:', file.hor or , ' ver:', file.ver or , ' link:', file.link or , ' alt:', file.alt or , ' page:', file.page or , ' class:', file.class or , ' lang:', file.lang or ''    end    return file end

function tableConcat (tab, delim, i, j)   -- concat for sparsed tables local s = {} for k, v in pairs(tab) do       table.insert(s, v)    end return table.concat(s, delim, i, j) end-- tableConcat

function toString(obj, delim) -- serialize file object to string local ret = {} if obj.name then table.insert(ret, obj.name) else return nil end delim = delim or '' local pattern = {'stuff', 'fmt', 'resize', 'hor', 'ver', 'alt', 'page', 'class', 'lang', 'link'} -- is param supposed to be named local isNamedParam for _, v in ipairs(pattern) do       isNamedParam = false if type(obj[v]) ~='nil' then local value = obj[v] if type(value) == 'table' then value = tableConcat(value, delim) end if reparams[v] then value = v .. '=' .. value end table.insert(ret, value) end end return table.concat(ret, delim) end-- toString

return p