模組:Element/sandbox

local p = {}
local origArgs
local error = require( 'Module:Error' )
local element_data = require( 'Module:Element/data' )

function p.symbol(frame)
	-- For calling from #invoke.
	local pframe = frame:getParent()
	local args = pframe.args
	return p._symbol(args)
end

function p.link(frame)
	-- For calling from #invoke.
	local pframe = frame:getParent()
	local args = pframe.args
	return p._link(args)
end

function p.check(frame)
	-- For calling from #invoke.
	local pframe = frame:getParent()
	local args = pframe.args
	return p._check(args)
end

function p.neutron(frame)
	-- For calling from #invoke.
	local pframe = frame:getParent()
	local args = pframe.args
	return p._neutron(args)
end

function p._neutron(args)
	--去除模板引用時可能產生的空格
	eleString='' if (args[1] and args[1] ~= '') then eleString = string.gsub(args[1] , "%s$", "") else return '' end
	eleid = p.getListID(eleString)
	ele1 = element_data[eleid]
	if (eleid==-1) then
		return ''
	end
	if (ele1.correct and ele1.correct  ~= '') then
		return ''
	end
	if (ele1.N and ele1.N ~= '') then
		return ele1.N
	end
	return ''
end

function p.protons(frame)
	-- For calling from #invoke.
	local pframe = frame:getParent()
	local args = pframe.args
	return p._protons(args)
end

function p._protons(args)
	--去除模板引用時可能產生的空格
	eleString='' if (args[1] and args[1] ~= '') then eleString = string.gsub(args[1] , "%s$", "") else return '' end
	eleid = p.getListID(eleString)
	ele1 = element_data[eleid]
	if (eleid==-1) then
		return ''
	end
	if (ele1.correct and ele1.correct  ~= '') then
		return ''
	end
	if (ele1.Z and ele1.Z ~= '') then
		return ele1.Z
	end
	return ''
end

function p._check(args)
	--去除模板引用時可能產生的空格
	eleString='' if (args[1] and args[1] ~= '') then eleString = string.gsub(args[1] , "%s$", "") else return error.error{ '未輸入元素' } end
	linkString='' if (args['link'] and args['link'] ~= '') then	linkString = string.gsub(args['link'] , "%s$", "") end
	if (linkString and linkString  ~= '') then
		if (linkString == 'yes') then
			pagetest=true
		end
	end
	eleid = p.getListID(eleString)
	ele1 = element_data[eleid]
	if (eleid==-1) then
		return error.error{ '未知的元素“' .. args[1] .. '”' } .. '[[Category:含有錯誤元素符號的條目]]'
	end
	if (ele1.correct and ele1.correct  ~= '') then
		return error.error{ '“' .. args[1] .. '”不是“'.. ele1.correct .. '”的正確拼法。' }
	end
	if (ele1.page and ele1.page ~= '') then
		return ''
	end
	if(pagetest)then
		return error.error{ '元素“' .. args[1] .. '”' .. '沒有對應的頁面。'}
	else
		return ''
	end
end

function p._symbol(args)
	if not(args[1] and args[1] ~= '') then return error.error{ '未輸入元素' } end
	myString = string.gsub(args[1] , "%s$", "") --去除模板引用時可能產生的空格
	eleid = p.getListID(myString)
	if (eleid==-1) then
		return error.error{ '未知的元素“' .. args[1] .. '”' } .. '[[Category:含有錯誤元素符號的條目]]'
	end
	ele1 = element_data[eleid]
	if(ele1.NotElement)then
		return ele1.Symbol
	end
	num = ele1.Z + ele1.N --計算質量數
	n = ele1.N
	number=tonumber(args[2])
	if (number and number  ~= '') then
		num = number
		n = num - ele1.Z
		if (n > 0) then --讀到有效的原子量才會進來這裡執行
			if (ele1.Isotope) then
				for v, x in ipairs(ele1.Isotope) do
					if (x.N == n) then
						if (x.Symbol and x.Symbol  ~= '') then
							return x.Symbol
						end
					end
				end
			end
		end
	end
	return ele1.Symbol 
end

function p._link(args)
	--去除模板引用時可能產生的空格
	arg1=''	if (args[1] and args[1] ~= '') then	arg1 = string.gsub(args[1] , "%s$", "") else return error.error{ '未輸入元素' } end
	arg2=''	if (args[2] and args[2] ~= '') then	arg2 = string.gsub(args[2] , "%s$", "") end
	arg3=''	if (args[3] and args[3] ~= '') then	arg3 = string.gsub(args[3] , "%s$", "") end
	eleid = p.getListID(arg1)
	has_m=''
	if (arg3 and arg3  ~= '') then
		has_m=arg3
	end
	if (eleid == -1) then
		return error.error{ '未知的元素“' .. arg1 .. '”' } .. '[[Category:含有錯誤元素符號的條目]]'
	end
	ele1 = element_data[eleid]
	if(ele1.NotElement)then
		return ele1.page
	end
	if (ele1.page and ele1.page  ~= '') then
		num = ele1.Z + ele1.N --計算質量數
		n = ele1.N
		hasmass=false
		number=tonumber(arg2)
		if (number and number  ~= '') then
			num = number
			n = num - ele1.Z
			hasmass=true
			if (n < 0) then
				return error.error{ '中子數不得為“' .. n .. '”' }
			end
		else
			if (args2 and args2 ~= '') then
				return error.error{ '未知的質量數“' .. args2 .. '”' }
			end
		end
		if (hasmass == true) then
			if (ele1.Isotope) then
				for v, x in ipairs(ele1.Isotope) do
					if (x.N == n) then
						if (x.page and x.page  ~= '') then
							return  x.page
						else
							return error.error{ '元素“' .. args[1] .. '”' .. '質量數為“'.. num  ..'”的同位素沒有對應的頁面。'}
						end
					end
				end
				return ele1.page .. '-' .. num .. has_m
			end
		end
		return ele1.page 
	end
	return error.error{ '元素“' .. args[1] .. '”' .. '沒有對應的頁面。'}
end

function p.getListID(names)
	local body =''         
	i=1
	for v, x in ipairs(element_data) do                                
		if ((x.name == names) or (x.page == names)) then
			return  i
		end
		for v1, x1 in ipairs(x.othername) do
			if (x1 == names) then
				return  i
			end
		end
		i=i+1
	end
	return -1 
end

function p.decaylink(frame)
	-- For calling from #invoke.
	local pframe = frame:getParent()
	local args = pframe.args
	return p._decaylink(args)
end

function p.elementlink(frame)
	-- For calling from #invoke.
	local pframe = frame:getParent()
	local args = pframe.args
	return p._elementlink(args)
end

function p._elementlink(args)
	arg1=''	if (args[1] and args[1] ~= '') then	arg1 = string.gsub(args[1] , "%s$", "") else return '' end
	arg2=''	if (args[2] and args[2] ~= '') then	arg2 = string.gsub(args[2] , "%s$", "") end
	eleid = p.getListID(arg1)
	if (eleid==-1) then
		return error.error{ '未知的元素“' .. arg1 .. '”' } .. '[[Category:含有錯誤元素符號的條目]]'
	end
	ele1 = element_data[eleid]
	symbol1=ele1.Symbol
	if(arg2 and arg2 ~= '')then if(arg2 ~= '1' )then
		if (ele1.compound)then symbol1 ='(' .. symbol1 .. ')' end
		symbol1 = symbol1 .. '<sub>' .. arg2 .. '</sub>'
	end end
	if (ele1.compound)then
		return '[[' .. ele1.page .. '|' .. symbol1 .. ']]'
	end
	if (ele1.NotElement)then
		return error.error{ '“' .. args[1] .. '”不是元素。'}
	end
	if (ele1.correct and ele1.correct  ~= '') then
		return error.error{ '“' .. args[1] .. '”不是“'.. ele1.correct .. '”的正確拼法。' }
	end
	if (ele1.page and ele1.page  ~= '') then
		return '[[' .. ele1.page .. '|' .. symbol1 .. ']]'
	else
		return error.error{ '元素“' .. args[1] .. '”沒有對應的頁面。'}
	end
	return ''
end

function p._element_symbol(args)
	arg1=''	if (args[1] and args[1] ~= '') then	arg1 = string.gsub(args[1] , "%s$", "") else return '' end
	arg2=''	if (args[2] and args[2] ~= '') then	arg2 = string.gsub(args[2] , "%s$", "") end
	eleid = p.getListID(arg1)
	if (eleid==-1) then
		return error.error{ '未知的元素“' .. arg1 .. '”' } .. '[[Category:含有錯誤元素符號的條目]]'
	end
	ele1 = element_data[eleid]
	symbol1=ele1.Symbol
	if(arg2 and arg2 ~= '')then if(arg2 ~= '1' )then
		if (ele1.compound)then symbol1 ='(' .. symbol1 .. ')' end
		symbol1 = symbol1 .. '<sub>' .. arg2 .. '</sub>'
	end end
	if (ele1.compound)then
		return symbol1
	end
	if (ele1.NotElement)then
		return error.error{ '“' .. args[1] .. '”不是元素。'}
	end
	if (ele1.correct and ele1.correct  ~= '') then
		return error.error{ '“' .. args[1] .. '”不是“'.. ele1.correct .. '”的正確拼法。' }
	end
	if (ele1.page and ele1.page  ~= '') then
		return symbol1
	else
		return error.error{ '元素“' .. args[1] .. '”沒有對應的頁面。'}
	end
	return ''
end

function p._decaylink(args)
	arg1=''	if (args[1] and args[1] ~= '') then	arg1 = string.gsub(args[1] , "%s$", "") else return '' end
	if(arg1=='p') then arg1='p+'end if(arg1=='n') then arg1='n0'end
	decayid = p.getListID(arg1)
	if (decayid==-1) then
		return ''
	end
	decay1 = element_data[decayid]
	if (decay1.decay)then
		return '[[' .. decay1.page .. '|' .. decay1.Symbol .. ']]'
	end
	return ''
end

p.IUPAC = { [0] = 'n', [1] = 'u', [2] = 'b', [3] = 't', [4] = 'q', [5] = 'p', [6] = 'h', [7] = 's', [8] = 'o', [9] = 'e' }
p.IUPAC_name = { [0] = 'nil', [1] = 'un', [2] = 'bi', [3] = 'tri', [4] = 'quad', [5] = 'pent', 
					[6] = 'hex', [7] = 'sept', [8] = 'oct', [9] = 'enn', [10] = 'ium', [11] = 'um' }

function p.DecodeByIUPAC_rules(symbol_data)
	symbol = mw.ustring.lower(symbol_data)
	symbol_len = mw.ustring.len(symbol)
	Z_data = ''
	for i = 1, symbol_len do
		get_id = nil
		for j = 0, 9 do if mw.ustring.sub(symbol ,i, i) == p.IUPAC[j] then get_id = j end end
		if get_id == nil then return nil end
		Z_data = Z_data .. get_id
	end
	return tonumber(Z_data)
end

function p.getElementByIUPAC_rules(index_input)
	result = ''
	result_name = ''
	index = tonumber(index_input)
	if index ~= nil then index = math.floor(index) else index = 0 end
	index_str = '' .. index
	index_len = mw.ustring.len(index_str)
	if index > 100 then
		for i = 1, index_len do
			data = p.IUPAC[tonumber('' .. mw.ustring.sub(index_str ,i, i)) or 0]
			name = p.IUPAC_name[tonumber('' .. mw.ustring.sub(index_str ,i, i)) or 0]
			if i == 1 then 
				result = result .. mw.ustring.upper(data)
				result_name = result_name .. mw.ustring.upper(mw.ustring.sub(name,1,1)) .. mw.ustring.sub(name,2,-1)
			else
				result = result .. data
				result_name = result_name .. name
			end
		end
	end
	if result == '' then
		return nil
	end
	result_name_index = 11 if mw.ustring.sub(result_name,-1,-1) ~= 'i' then result_name_index = result_name_index - 1 end
	return { name=result_name .. p.IUPAC_name[result_name_index] , page=result, Symbol=result, Z=index }
end

function p.getElementByZ(index)
	local body =''         
	for v, x in ipairs(element_data) do                                
		if (x.Z == index) then
			return  x
		end
	end
	if index > 0 then
		return p.getElementByIUPAC_rules(index)
	end
	return nil 
end

function p.next_element(symbol)
	eleid = p.getListID(symbol)
	ele1 = element_data[eleid]
	
	if ele1 == nil then ele_z = p.DecodeByIUPAC_rules(symbol) else if ele1.Z == nil then
		ele_z = p.DecodeByIUPAC_rules(symbol) else ele_z = ele1.Z end
	end

	if ele_z ~= nil then
		return p.getElementByZ(ele_z + 1)
	end
	return nil
end

function p.last_element(symbol)
	eleid = p.getListID(symbol)
	ele1 = element_data[eleid]
	
	if ele1 == nil then ele_z = p.DecodeByIUPAC_rules(symbol) else if ele1.Z == nil then
		ele_z = p.DecodeByIUPAC_rules(symbol) else ele_z = ele1.Z end
	end

	if ele_z ~= nil then
		return p.getElementByZ(ele_z - 1)
	end
	return nil
end

--本模塊的沙盒(測試)函數
function p.sandbox(frame)
	-- For calling from #invoke.
	local pframe = frame:getParent()
	local args = pframe.args
	return p._elementlink(args)
end
function p._sandbox(args)
	return element_data[p.getListID(args[1])].name 
end
return p