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

ifnewhtmlline

判斷輸入字串中是否存在HTML的換行標籤

noTrim

由於預設的解析器函數(如{{#if:}}{{#ifexpr:}})會自動將輸入的參數做去除頭尾空白或斷行字元的操作

這對部分需要使替換引用結果出現換行又要避免出現尾部佔位符(如在換行後加入<!---->{{void}}等作法避免trim)是不可行的,或者需要較複雜的語法書寫方式,這將使的模板代碼的可讀性和可維護性變得十分的差,並且增加模板展開調用甚至可能增加維基媒體伺服器的運作負擔。

因此為了解決{{#if:}}{{#ifexpr:}}{{if}}會自動將參數trim掉的問題,因此這個模組透過Module:Arguments將關閉參數trim功能提供了一個解決方案。

基本用法

{{#invoke:ifUtil|noTrim|命令|判斷參數|成立時返回|不成立時返回}}

簡易用法
  • {{#if:}}
    • {{#if:判斷|符合|否則}} (會自動trim
    • trim版:{{#invoke:ifUtil|noTrim|if|判斷|符合|否則}}
  • {{#ifeq:}}
    • {{#ifeq:內容1|內容2|相等|不同}} (會自動trim
    • trim版:{{#invoke:ifUtil|noTrim|eq|內容1|內容2|相等|不同}}
  • {{yesno}}
    • {{yesno|布林值|yes=為真時|no=為假時}} (會自動trim
    • trim版:{{#invoke:ifUtil|noTrim|yesno|布林值|為真時|為假時}}
  • {{#ifexpr:}}
    • {{#ifexpr:判斷式|為真時|為假時}} (會自動trim
    • trim版:{{#invoke:ifUtil|noTrim|expr|判斷式|為真時|為假時}}
  • {{#iferror:}}
    • {{#iferror:測試內容|有錯時|正常時}} (會自動trim
    • trim版:{{#invoke:ifUtil|noTrim|error|測試內容|有錯時|正常時}}
  • {{#ifexist:}}
    • {{#ifexist:頁面標題|存在時|沒有時}} (會自動trim
    • trim版:{{#invoke:ifUtil|noTrim|exist|頁面標題|存在時|沒有時}}
進階用法
  • {{yesno}}
    • 參數順序:{{#invoke:ifUtil|noTrim|yesno|布林值|為真時(yes)|為假時(no)|空白時(blank)|非法輸入時(def)|未定義時(¬)}}
  • if...elseif...else
    • {{#invoke:ifUtil|noTrim|expr|判斷式1|式1為真時|式1為假時}}
    • {{#invoke:ifUtil|noTrim|expr|判斷式1|式1為真時|elseif判斷式2|式2為真時}}
    • {{#invoke:ifUtil|noTrim|expr|判斷式1|式1為真時|elseif判斷式2|式2為真時|皆為假時}}
    • {{#invoke:ifUtil|noTrim|expr|判斷式1|式1為真時|elseif判斷式2|式2為真時|elseif判斷式3|式3為真時}}
    • {{#invoke:ifUtil|noTrim|expr|判斷式1|式1為真時|elseif判斷式2|式2為真時|elseif判斷式3|式3為真時|皆為假時}}
    • 以此類推,參數長度沒有上限 (除了WP:模板限制
比較

注意留意「文字」與「Yse/No」模板間的空格狀況

項目 使用Module:IfUtil#noTrim 使用Help:解析器函數
您所輸入的 您所看到的 您所輸入的 您所看到的
#ifexpr:
文字{{#invoke:IfUtil|noTrim|expr|5>3|
Yes
|
No
}}文字
文字

Yes 文字

文字{{#ifexpr:5>3|
Yes
|
No
}}文字
文字Yes文字
#ifexpr:
文字{{#invoke:IfUtil|noTrim|expr|5<3|
Yes
|
No
}}文字
文字

No 文字

文字{{#ifexpr:5<3|
Yes
|
No
}}文字
文字No文字
#ifeq:
文字{{#invoke:IfUtil|noTrim|eq|A|A|
Yes
|
No
}}文字
文字

Yes 文字

文字{{#ifeq:A|A|
Yes
|
No
}}文字
文字Yes文字
#ifeq:
文字{{#invoke:IfUtil|noTrim|eq|A|B|
Yes
|
No
}}文字
文字

No 文字

文字{{#ifeq:A|B|
Yes
|
No
}}文字
文字No文字
yesno:是
文字{{#invoke:IfUtil|noTrim|yesno||
Yes
|
No
}}文字
文字

Yes 文字

文字{{yesno||yes=
Yes
|no=
No
}}文字
文字Yes文字
#ifexist:
無此條目!!
文字{{#invoke:IfUtil|noTrim|exist|無此條目!!|
Yes
|
No
}}文字
文字

No 文字

文字{{#ifexist:無此條目!!|
Yes
|
No
}}文字
文字No文字
#ifexist:
WP:條目
文字{{#invoke:IfUtil|noTrim|exist|WP:條目|
Yes
|
No
}}文字
文字

Yes 文字

文字{{#ifexist:WP:條目|
Yes
|
No
}}文字
文字Yes文字

所有命令

命令 基本用法 描述
常規判斷
if {{#invoke:ifUtil|noTrim|if|判斷的字串|字串有值時返回|字串為空時返回}} {{#if:}}的不trim版本。
expr {{#invoke:ifUtil|noTrim|expr|expr表達式|表達式為真時返回|表達式為假時返回}} {{#ifexpr:}}的不trim版本。
內容比對
eq {{#invoke:ifUtil|noTrim|eq|判斷的字串|字串有值時返回|字串為空時返回}} {{#ifeq:}}的不trim版本。
eq|選項=Y/N {{#invoke:ifUtil|noTrim|eq|選項1=Y/N|選項2=Y/N|判斷的字串|字串有值時返回|字串為空時返回}} 特殊選項的{{#ifeq:}}。目前的選項有:
  • |trim=:不去除頭尾空格比較字串,預設為yes。
  • |i=:是否忽略大小寫,預設為no。
  • |unstrip=:是否忽略擴展標籤,預設為no。
  • |preprocess=:是將傳入的字串視為維基代碼並再做一次解析,預設為no。

可疊加多個選項。

eq|trim=no {{#invoke:ifUtil|noTrim|eq|trim=no|比對的字串1|比對的字串2|字串相等時返回|字串不同時返回}} 連輸入欲比對之字串都不trim{{#ifeq:}}。其會將「foo 」與「foo」視為相異。
eq|i=yes {{#invoke:ifUtil|noTrim|eq|i=yes|比對的字串1|比對的字串2|字串相等時返回|字串不同時返回}} 忽略大小寫的trim{{#ifeq:}}。其會將「FOO」與「foo」視為相同。
內容判斷
error {{#invoke:ifUtil|noTrim|error|欲除錯的內容|內容有錯誤時返回|內容沒有問題時返回}} {{#iferror:}}的不trim版本。
exist {{#invoke:ifUtil|noTrim|exist|要判斷是否存在的頁面標題|頁面存在時返回|頁面不存在時返回}} {{#ifexist:}}的不trim版本。
工具
yesno {{#invoke:ifUtil|noTrim|yesno|可代表布林值的字串|布林值為真時返回|布林值為假時返回}} {{yesno}}的不trim版本[a],同時也支援{{yesno}}的。|yes=|no=|def==|blank=等參數。(參見#進階用法#yesno
其他if-else類模板 {{#invoke:ifUtil|noTrim|<其他if-else類模板>|判斷用參數|成立時返回|不成立時返回}} 其他if-else類模板的不trim版本[a]
其他模板[b] {{#invoke:ifUtil|noTrim|<模板名稱>|參數1|參數2|參數3....}} 對於不支援或非if-else類的模板會有類似一般地調用模板的效果。
  1. ^ 1.0 1.1 這類模板如{{yesno}}同樣是透過普通的Help:解析器函數實現,因此仍會有trim的問題。此處透過嘗試接收{{模板名稱|判斷式|yes|no}}的輸出來決定要返回哪個未trim參數,若失敗則當作一般模板調用。
  2. ^ if-else模板測試失敗時的效果。

參數

下表按固定顺序显示了可用的位置参数(参数*)。对于每个命令,都会标记适用的参数集。例如,如果已给出命令 eq,那么至少应给出 判斷式①比對式 兩個参数。

(必要) (必要) (ifeq必填) (可选) (可选) (可选) (可选)
{{#invoke:ifUtil|noTrim 命令 判斷式① 比對式 ①成立時 否則 判斷式② ②成立時 判斷式③... }}
其他參數 其他參數2 其他參數3...
if, expr,
eq,error,
exist,yesno,
其他if-else類模板,
其他模板
eq
if, expr,eq,error,
exist,yesno(yes參數),其他if-else類模板
if, expr, eq,error,
exist,yesno(no參數), 其他if-else類模板
expr, yesno(blank參數), 其他模板
expr, yesno(def參數), 其他模板 (可选 2nd, 3rd 等)
expr (可选 2nd, 3rd 等), yesno(¬參數), 其他模板

if2number

local p={}
local lib_arg={}
local yesno = require('Module:Yesno')

function p.noTrim(frame)--{{#invoke:IfUtil|noTrim|expr|5>3|Yes|No}}
	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,
        	trim = false,
			removeBlanks = false
        })
        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 command = mw.ustring.lower(mw.text.trim(args['1'] or args[1] or ''))
    local if_table = require('Module:Var')._seek_arg(args,1)
    if command == 'if' or command == '' or command == '#if' then
    	return p.ifnoTrim(if_table)
    elseif command == 'ifexpr' or command == 'expr' or command == '#ifexpr' then
    	return p.ifexprnoTrim(if_table)
    elseif command == 'ifeq' or command == 'eq' or command == '#ifeq' then
    	local strcmpi, unstrip, preprocess = yesno(mw.text.trim(args.i or 'no')), yesno(mw.text.trim(args.unstrip or 'no')), yesno(mw.text.trim(args.preprocess or 'no'))
    	local pre_str = function(in_str)
    		local result = in_str
    		if preprocess == true then result = working_frame:preprocess(result) end
    		if unstrip == true then result = mw.text.unstrip(result) end
    		if strcmpi == true then result = mw.ustring.lower(result) end
    		return result 
    	end
    	if yesno(mw.text.trim(args.trim or 'yes')) then
    		if mw.text.trim(pre_str(args['2'] or args[2] or '')) == mw.text.trim(pre_str(args['3'] or args[3] or '')) then return args['4'] or args[4] or ''
    		else return args['5'] or args[5] or '' end
    	else
    		if pre_str(args['2'] or args[2] or '') == pre_str(args['3'] or args[3] or '') then return args['4'] or args[4] or ''
    		else return args['5'] or args[5] or '' end
    	end
    elseif command == 'iferror' or command == 'error' or command == '#iferror' then
	    local output_error = args['3'] or args[3] or ''
	    local output_success = args['4'] or args[4]
    	if not output_success then output_success = args['2'] or args[2] or '' end
    	local result = working_frame:callParserFunction{ name = '#iferror:' .. mw.text.trim(args['2'] or args[2] or ''), args = {'error', 'success'} }
    	result = mw.ustring.lower(result)
    	if result == 'success' then return output_success end
    	return output_error
    elseif command == 'ifexist' or command == 'exist' or command == '#ifexist' then
	    local output_exist = args['3'] or args[3]
	    local output_no = args['4'] or args[4] or ''
    	if not output_exist then output_exist = args['2'] or args[2] or '' end
    	local result = working_frame:callParserFunction{ name = '#ifexist:' .. mw.text.trim(args['2'] or args[2] or ''), args = {'1', '0'} }
    	result = mw.ustring.lower(result)
    	if result == '1' then return output_exist end
    	return output_no
    elseif command == 'yesno' then
    	--1=yesno | 2=test | 3=yes | 4=no | 5=blank | 6=def | 7=¬
    	local checker = mw.ustring.lower(mw.text.trim(args['2'] or args[2]or''))
    	if (not (args['2'] or args[2])) or checker == '¬' then return args['¬'] or args['7'] or args[7] or ''end
    	if checker=='' then return (args.blank or args['5'] or args[5]) or (args.no or args['4'] or args[4]) or '' end
		checker = yesno(checker)
    	if checker == true then
    		return args.yes or args['3'] or args[3] or 'yes'
    	elseif checker == false then
    		return args.no or args['4'] or args[4] or ''
    	end
    	return args.def or args['6'] or args[6] or ''
    else 
    	local yes_arg, no_arg = args['yes arg'] or args.yes_arg or '2', args['no arg'] or args.no_arg or '3'
    	local if_check_table_input = require('Module:Var')._seek_arg(args,1)
    	if_check_table_input[yes_arg], if_check_table_input.yes = "yes", "yes"
    	if_check_table_input[no_arg], if_check_table_input.no = "no", "no"
    	local if_check_table = {}
    	for key, value in pairs(if_check_table_input) do
    		local num_key = tonumber(key)
    		if type(num_key) ~= type(nil) then --是數字參數 (匿名參數)
    			if_check_table[num_key] = value --避免數字參數重複以清理[[:Category:调用重复模板参数的页面]]
    		else
    			if_check_table[key] = value
    		end
    	end
    	local tester = mw.ustring.gsub(mw.text.unstrip(mw.ustring.lower(mw.text.trim(working_frame:preprocess(require('Module:Template invocation').invocation( 'safesubst:' .. (args['1'] or args[1] or 'void'), if_check_table))))), "<[^>]+>", '')
    	local checker = yesno(mw.ustring.sub(tester, mw.ustring.find(tester,'%a+')))
    	if checker == true then return args['3'] or args[3] or ''
    	elseif checker == false then return args['4'] or args[4] or ''end
    	return working_frame:preprocess(require('Module:Template invocation').invocation( 'safesubst:' .. (args['1'] or args[1] or 'void'), if_table))
    end
    return ''
end

function p.ifexprnoTrim(frame)--{{#invoke:IfUtil|ifexprnoTrim|5>3|Yes|No}}
	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,
        	trim = false,
			removeBlanks = false
        })
        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 input_str = args['1'] or args[1] or '0'
    local output_if = args['2'] or args[2] or ''
    local check_max_arg = 2
    local ifexpr_table = {}
    for k,v in pairs(args) do
    	local check_num = tonumber(mw.text.trim(k))
    	if check_num and check_num > check_max_arg then
    		check_max_arg = check_num
    	end
    	ifexpr_table[k] = v
    end
    ifexpr_table['1'] = input_str
    ifexpr_table['2'] = output_if
    local tail = check_max_arg - check_max_arg % 2
    local output_else = (check_max_arg % 2 == 1) and (args[tostring(check_max_arg)] or args[check_max_arg]) or ''
    for i=1,tail,2 do
    	local expr = ifexpr_table[tostring(i)] or ifexpr_table[i] or '0'
    	local true_result = args[tostring(i+1)] or args[i+1] or ''
    	local flag,ifexpr = xpcall(function() return mw.ext.ParserFunctions.expr(expr)end,function()end)
    	--use original #ifexpr: to print original error
    	if flag~=true then return working_frame:preprocess("{{safesubst:#ifexpr:" .. expr .. '|' .. true_result .. '|' .. output_else .."}}") end
    	if (tonumber(ifexpr or'0') or 0) ~= 0 then return true_result end
    end
    return output_else
end

function p.ifnoTrim(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,
        	trim = false,
			removeBlanks = false
        })
        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 input_str = args['1'] or args[1] or ''
    local output_if = args['2'] or args[2] or ''
    local output_else = args['3'] or args[3] or ''
    if mw.text.trim(input_str) ~= '' then
    	return output_if
    end
    return output_else
end

function p.ifnewhtmlline(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,
        	trim = false,
			removeBlanks = false
        })
        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 input_str = args['1'] or args[1] or ''
    local output_if = args['2'] or args[2] or ''
    local output_else = args['3'] or args[3] or ''
    if mw.ustring.find(input_str, '<%s*/?%s*[Bb][Rr]%s*/?%s*>') then
    	return output_if
    end
    return output_else
end

function p.ifnoAddTail(frame) --{{#invoke:IfUtil|ifnoAddTail|text|unit|pattern}}
	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, {
        	trim = false,
			removeBlanks = false
        })
        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 input_str = args['1'] or args[1] or ''
    local uint = args['2'] or args[2] or ''
	local uint_pattern = args['3'] or args[3] or ''
	if mw.text.trim(uint_pattern) == '' then uint_pattern = mw.ustring.gsub(mw.text.trim(uint), '([%\\%^%$%(%)%%%.%{%}%[%]%*%+%-%?])','%%%1')end
    if mw.ustring.find(input_str, uint_pattern) then
    	return input_str
    end
    return input_str .. uint
end

function p.if2number(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,
        	trim = false,
			removeBlanks = false
        })
        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 input_str = args['1'] or args[1] or ''
    local output_hasTwo = args['2'] or args[2] or '1'
    local output_otherwise = args['3'] or args[3] or ''
    local check_split = args['4'] or args[4] or '~'
    local local_check = mw.text.trim(require('Module:TemplateParameters').containsNumber({input_str}))
    if local_check ~= '' then
    	local split_end, split2_first = mw.ustring.find(input_str,check_split)
    	local first_num_str, second_num_str = '', ''
    	if split_end then first_num_str = mw.ustring.sub(input_str,1,split_end-1) end
    	if split2_first then second_num_str = mw.ustring.sub(input_str,split2_first+1,-1) end
    	local first_num_check, second_num_check = mw.text.trim(require('Module:TemplateParameters').containsNumber({first_num_str})),
    		mw.text.trim(require('Module:TemplateParameters').containsNumber({second_num_str}))
    	if first_num_check ~= '' and second_num_check ~= '' then
    		first_num_check, second_num_check = require('Module:TemplateParameters').getNumberValue({first_num_str}),
    			require('Module:TemplateParameters').getNumberValue({second_num_str})
    		local first_num, second_num = tonumber(first_num_check), tonumber(second_num_check)
    		if first_num and second_num then
    			if first_num ~= second_num then
    				return output_hasTwo
				else return output_otherwise end
			else return output_otherwise end
    	else return output_otherwise end
    else return output_otherwise end
end

function p.findArgs(frame)
	-- For calling from #invoke.
    local args
    --是否存在有效的frame可供呼叫
    local can_call_parse = false
    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.
        args = frame.args
        can_call_parse = true
    else
        -- We're being called from another module or from the debug console, so assume
        -- the args are passed in directly.
        args = frame
    end
    local out_frame = mw.getCurrentFrame():getParent() --模板外層
    local out_args = {} --紀錄來自模板外層提供的參數
    local body = ''
    local to_find={}
    local default=''
    
    if out_frame then out_args = out_frame.args or out_args end
    for key,val in pairs(args) do
    	local parse_name=tonumber(key)
    	if parse_name then to_find[#to_find+1]=val end
    end
    default = args.default or default
    local find_result={}
    local is_find=false
    for key,val in pairs(out_args) do
    	for i=1,#to_find do
	    	if mw.ustring.lower(mw.text.trim(val)) == mw.ustring.lower(mw.text.trim(to_find[i])) then
	    		is_find=true
	    		find_result[mw.text.trim(key)]=is_find;
	    	end
    	end
    end
    if is_find then
    	local body = ''
    	for key,val in pairs(find_result) do 
    		if body~='' then body=body..','end
    		body=body..key
    	end
    	return body
    else
    	return default
    end
end

return p