模組:Geometric Shape Example

文档图示 模块文档[查看] [编辑] [历史] [清除缓存]

提供{{Geometric Shape Example}}支援

local p={}
local lib_arg={}

local function in_array(obj, arr)
	for _, value in pairs(arr) do
		if value == obj then return true end
	end
	return false
end

local function nonZero(x)
	return math.abs(x) > 1e-8
end

local function findGcd(a, b)
	local r, oldr = tonumber(b), tonumber(a)
	while nonZero(r) do local mod_val = oldr % r oldr, r = tonumber(r), mod_val end
	if oldr < 0 then oldr = -oldr end
	return oldr
end

local function findLcm(a, b)
	return math.abs(a * b) / findGcd(a, b)
end

local function newpagetitle(title)
	local result = nil
	success, result = pcall(mw.title.new, title)
	if not success then return nil end
	return result
end

local function normalizeStringMark(str_input)
	if mw.ustring.find(str_input, '"') then
		return "'" .. mw.ustring.gsub(str_input, "'", '"') .. "'"
	elseif mw.ustring.find(str_input, "'") then
		return '"' .. mw.ustring.gsub(str_input, '"', "'") .. '"'
	end
	return "'" .. mw.ustring.gsub(str_input, "'", '"') .. "'"
end

function p.main(frame)
    local args, working_frame
    if frame == mw.getCurrentFrame() then
        -- We're being called via #invoke. The args are passed through to the module
        -- from the template page, so use the args that were passed into the template.
        if lib_arg.getArgs == nil then lib_arg = require('Module:Arguments') end
        args = lib_arg.getArgs(frame, {parentFirst=true})
        working_frame = frame
    else
        -- We're being called from another module or from the debug console, so assume
        -- the args are passed in directly.
        args = frame
        working_frame = mw.getCurrentFrame()
        if type(args) ~= type({}) then args = {frame} end
    end
    local example_data = {}
    local width_count = tonumber(args.width_count or args["width count"]) or 2
    local tail_count_to_first = (args.tail_count_to_first or args["tail count to first"]) and (require('Module:Yesno'))(args.tail_count_to_first or args["tail count to first"], false) or false

    for key, value in pairs(args) do
    	local arg_name, arg_id = nil, nil
    	local check_key = mw.text.trim(tostring(key))
    	mw.ustring.gsub(check_key, "^(.-)(%d+)(.*)", function(m_arg_name, m_arg_id, m_tail_value) 
    		if mw.text.trim(m_arg_name or "") == "" and mw.text.trim(m_tail_value or "") ~= "" then
    			arg_name, arg_id = mw.ustring.lower(mw.text.trim(m_tail_value)), m_arg_id
    		elseif mw.text.trim(m_arg_name or "") ~= "" and mw.text.trim(m_tail_value or "") ~= "" then
    			return (m_arg_id or "")..(m_arg_name or "")..(m_tail_value or "")
    		else
    			arg_name, arg_id = mw.ustring.lower(mw.text.trim(m_arg_name)), m_arg_id
    		end return ""
    	end)
		if in_array(check_key, {
			"content", "內容", "文件", "档案", "檔案", "媒体", "媒體",
			"file","image","图像","圖像","文件","档案","檔案",
			"media","媒体","媒体文件","媒體",
			"name", "名稱", "名称",
			"type", "類型", "类型", "種類", "种类",
			"caption", "description", "說明", "说明", "描述",
			"size", "尺寸", "大小"
		}) then 
			arg_id = 1
			arg_name = check_key
		end
    	local i = tonumber(arg_id)
		if i ~= nil then
			if arg_name or arg_id then
	    		arg_name = arg_name or ""
	    		if in_array(arg_name, {"", "content", "內容", "文件", "档案", "檔案", "媒体", "媒體"}) then
	    			local local_data = example_data[i] or {}
	    			filename = value
	    			mw.ustring.gsub(filename,"^:?([^:]+):([^\n]+)$", function(page_ns, page_name)
	    				local check_ns = mw.text.trim(mw.ustring.lower(page_ns))
	    				local media_ns = {
	    					"file","image","图像","圖像","文件","档案","檔案",
	    					"media","媒体","媒体文件","媒體"
	    				}
	    				if in_array(check_ns, media_ns) then
	    					filename = mw.text.trim(page_name)
	    				end
	    			end)
	    			if ({mw.ustring.find(value,"\n")})[1] or not ({mw.ustring.find(value,"%.")})[1] then
	    				local_data.body = value
	    			elseif ((newpagetitle("Image:"..filename) or {}).file or {}).exists then
	    				local_data.filename = "Image:"..filename
	    			else local_data.body = value end
	    			example_data[i] = local_data
				elseif in_array(arg_name, {"name", "名稱", "名称"}) then
					local local_data = example_data[i] or {}
	    			local_data.name = value
	    			example_data[i] = local_data
				elseif in_array(arg_name, {"type", "類型", "类型", "種類", "种类"}) then
					local local_data = example_data[i] or {}
	    			local_data.type = value
	    			example_data[i] = local_data
				elseif in_array(arg_name, {"caption", "description", "說明", "说明", "描述"}) then
					local local_data = example_data[i] or {}
	    			local_data.caption = value
	    			example_data[i] = local_data
				elseif in_array(arg_name, {"size", "尺寸", "大小"}) then
					local local_data = example_data[i] or {}
					local size = tostring(value)
					if not ({mw.ustring.find(value,"px")})[1] then size = size .. "px" end
	    			local_data.size = size
	    			example_data[i] = local_data
				elseif in_array(arg_name, {"style", "樣式", "样式"}) then
					local local_data = example_data[i] or {}
	    			local_data.style = value
	    			example_data[i] = local_data
				elseif in_array(arg_name, {"style_class", "style class", "class"}) then
					local local_data = example_data[i] or {}
	    			local_data.style_class = value
	    			example_data[i] = local_data
	    		end
			end
		end
    end
    local max_example = 0
    for _, shape_item in pairs(example_data) do 
    	--計算有效的圖片數量
    	if shape_item.body or shape_item.filename then
    		max_example = max_example + 1 
    	end
    end
    --沒有有效的圖片返回空
    if max_example <= 0 then return '' end
    --計算最後一行剩幾個
    local tail_count = max_example % width_count
    --表格總共要幾欄
    local all_colspan = width_count
    local all_rows = math.ceil(max_example / width_count)
    --最後一行未滿的
    local has_not_complete = nonZero(tail_count)
    if has_not_complete then all_colspan = findLcm(width_count, tail_count) end
    --一般欄的數 (要對應最後一行未滿的情況)
    local normal_span = all_colspan / width_count
    
    local style = mw.ustring.gsub(args.style or '', '"', "'")
    local style_class = mw.ustring.gsub(args.style_class or args["style class"] or "", '"', "'")
    body = '{| class="infobox ' .. style_class
    	.. '" style="float: right; margin: 0 0 1em 1em; width: 22.5em; font-size: 0.86em; line-height: normal; border: 1px solid #CCD2D9; background: #F0F6FA; '
    	.. style ..'"\n'
    if mw.text.trim(args.shape_class or args["shape class"] or"")~="" then body = body.."|+ '''"..(args.shape_class or args["shape class"]).."'''\n" end
    body = body .. '! colspan='..all_colspan..' style="padding-top:1.0em; padding-bottom:1.0em;"|'
    body = body .. "<big>"
    if mw.text.trim(args.title or"")~="" then body = body .. args.title 
    else body = body .. "部分的" .. ((mw.text.trim(args.shape_class or args["shape class"] or"")~="")and(args.shape_class or args["shape class"])or"形狀")
    end
    body = body .. "</big>\n"

    local i = 0
    for _, shape_item in pairs(example_data) do
    	if shape_item.body or shape_item.filename then
    		local add_colspan = normal_span
    		local j, k = i, i
    		if tail_count_to_first then j, k = max_example - i - 1, i - tail_count + width_count * all_rows end
    		if k % width_count == 0 or i == 0 then body = body.."|-\n"end
    		--如果最後一行未滿,且已經到最後一行了
    		if has_not_complete and (((j + (1 / width_count)) / width_count) + 1) >= all_rows then
    			--平均分配最後一行
    			add_colspan = all_colspan / tail_count
    		end
    		
    		body = body .. '| align="center"'
    		if add_colspan > 1 then
    			body = body .. " colspan=" .. add_colspan
    		end
    		local style_body = "vertical-align: middle; "
    		if shape_item.style and mw.text.trim(shape_item.style or "") ~= "" then
    			if mw.ustring.find(shape_item.style, "vertical%-align") then
    				style_body = shape_item.style
    			else
    				style_body = style_body .. shape_item.style
    			end
    		end
    		body = body .. " style=" .. normalizeStringMark(style_body)
    		if shape_item.style_class and mw.text.trim(shape_item.style_class or "") ~= "" then
    			body = body .. " class=" .. normalizeStringMark(shape_item.style_class)
    		end
    		body = body .. '|'
    		if shape_item.filename then
				body = body .. "[[" .. shape_item.filename .. '|' .. (shape_item.size or "120px")
					..	(shape_item.caption and('|'..shape_item.caption)or
						(shape_item.name and('|'..shape_item.name)or"") )
					..  (shape_item.caption and("|alt="..shape_item.caption)or'')
					.. "]]"
			end
			body = body .. (shape_item.body and ((
					(shape_item.filename and (shape_item.caption or shape_item.name)) 
					and "<br/>" or "") .. shape_item.body) or '')
			body = body .. (shape_item.name and ("<br/>"..shape_item.name) or '')
			body = body .. (shape_item.type and ("<br/>("..shape_item.type..")") or '') 
			body = body .. (shape_item.caption and ("<br/><small>"..shape_item.caption.."</small>") or '')
    		body = body .. "\n"
    		i = i + 1
    	end
    end
    body = body .. "|-\n|}"
    return body
end
return p