Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:File parse

From Wikipedia, the free encyclopedia

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;