全站通知:

模块:Ref

来自黑神话:悟空WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:Ref/doc创建

-- 本模块参考了 萌娘百科 模块:Var(zh.moegirl.org.cn/模块:Var) 和 模块:Var-array/main (zh.moegirl.org.cn/模块:Var-array/main)
local frame = mw.getCurrentFrame()
local list = require('Module:List')
local p = {}
local v = {}

function empty(s)
  return s == nil or s == '' or s == 'nil'
end

function notempty(s)
  return not empty(s)
end

function default(val,fallback)
	if empty(val) then
		return fallback
	else
		return val
	end
end

function v.get(key, fallback)
	local key = tostring(key)
	local fallback = tostring(fallback)

	local val = frame:callParserFunction("#var", key)
	if empty(val) and notempty(fallback) then
		return fallback
	end
    return val
end

function v.set(key, val)
    frame:callParserFunction("#vardefine", tostring(key), tostring(val))
end

function v.del(key)
    frame:callParserFunction("#vardefine", tostring(key), '')
end

function v.minus(key,num)
	local key = tostring(key)
	local num = tonumber(default(num, 1))
	local val = frame:callParserFunction("#var", key)
	if not val or val == '' then
		val = 0
	else
		val = tonumber(val)
	end
    frame:callParserFunction("#vardefine", key, val - num)
end

function v.add(key, num)
	local key = tostring(key)
	local num = tonumber(default(num, 1))
	local val = frame:callParserFunction("#var", key)
	if not val or val == '' then
		val = 0
	else
		val = tonumber(val)
	end
    frame:callParserFunction("#vardefine", key, val + num)
end

function p.ref(frame)
  local group = default(frame.args["group"],'default') -- 所有的cite都有group
  local content = frame.args[1]
  local name = frame.args['name']
  local sub = frame.args["sub"]  -- 支持子引用
  local append = frame.args["append"]
  
  -- 参数检查
  if notempty(content) and (notempty(sub) or notempty(append)) then
    return "当给出参数1时,不支持使用 sub 或 append 参数" .. frame.args[1] .. 'end'
  end
  if empty(name) and (notempty(sub) or notempty(append)) then
    error("使用 sub 或 append 参数 时,必须指定 name 参数")
  end
  if empty(name) and empty(content) then
    error("内容和name不能同时为空")
  end
  
  -- 创建引用,涉及的参数:group、content、name
  if empty(sub) and empty(append) then

  	-- 检查group是否存在。不存在就要新建
  	if empty(v.get('group_' .. group .. '_i')) then
  	  -- group 不存在,group count+1 , 
	  v.add('list_groups_i') -- list_groups_i += 1
      v.set('list_groups_' .. v.get('list_groups_i'), group) -- list_groups_i = group
  	end
  	
  	local cite_index = ''
  	if empty(content) and notempty(name) and notempty(v.get('cite_' .. name .. '.index')) then
  		cite_index = v.get('cite_' .. name .. '.index')
  	else
  		v.add('cite_index')
  		cite_index = v.get('cite_index')
  	end
  	
  	local cite_name = default(name, cite_index)
  	local cite_link_id = 'cite-' .. group .. '-' .. cite_index -- for backlink
  	local ref_link_id = 'ref-' .. group .. '-' .. cite_index -- for jump to ref
    -- 向这个group中增加name
    v.add('group_' .. group .. '_i')  -- group_name_i += 1
    v.set('group_' .. group .. v.get('group_' .. group .. '_i'), cite_name)

    -- 存放name数据
	v.set('cite_idx' .. cite_index, cite_name)
	v.set('cite_' .. cite_name .. '.index', cite_index)
	v.set('cite_' .. cite_name .. '.group', group)
	v.set('cite_' .. cite_name .. '.content', content)
	v.set('cite_' .. cite_name .. '.cite_link_id', cite_link_id)
    v.set('cite_' .. cite_name .. '.ref_link_id', ref_link_id)
    
    local html = mw.html.create()
    -- todo 改为模板
    local cite_html = html
      :tag('sup'):attr('id', cite_link_id):addClass('reference')
        :wikitext('[[#'.. v.get('cite_' .. cite_name .. '.ref_link_id')  ..'|['.. v.get('cite_' .. cite_name .. '.index') ..']]]')
      :done()
    return tostring(cite_html)
  end

  --if empty(sub) and empty(append) and empty(content) then
  --  local html = mw.html.create()
  --  -- todo 改为模板
  --  local cite_html = html
  --    :tag('sup'):attr('id', v.get('cite_' .. name .. '.cite_link_id')):addClass('reference')
  --      :wikitext('[[#'.. v.get('cite_' .. name .. '.ref_link_id')  ..'|['.. v.get('cite_' .. name .. '.index') ..']]]')
  --    :done()
  --  return tostring(cite_html)
  --end

  -- 支持 append,只需要修改对应的数据
  if notempty(append) then
    v.set('cite_' .. tostring(name) .. '.content', v.get('cite_' .. tostring(name) .. '.content') .. append)
  end
  
  -- 支持sub,存储子引用
  if notempty(sub) then
  	--v.add('cite_index')
  	--local cite_index = v.get('cite_index')

  	v.add('cite_' .. name .. '.sub_i')
  	local sub_cite_index = v.get('cite_' .. name .. '.sub_i')
  	
  	local cite_link_id = 'cite-' .. v.get('cite_' .. name .. '.group') .. '-sub' .. sub_cite_index -- for backlink
  	local ref_link_id = 'ref-' .. v.get('cite_' .. name .. '.group') .. '-sub' .. sub_cite_index -- for jump to ref
  	
    v.set('cite_' .. name .. '.sub' .. sub_cite_index .. '.cite_link_id', cite_link_id)
    v.set('cite_' .. name .. '.sub' .. sub_cite_index .. '.ref_link_id', ref_link_id)
    v.set('cite_' .. name .. '.sub' .. sub_cite_index .. '.content', sub)
    
    local main_index = 	v.get('cite_' .. name .. '.index')
    -- 输出 sup 引用
    local html = mw.html.create()
    -- todo 改为模板
    local cite_html = html
      :tag('sup'):attr('id', cite_link_id ):addClass('reference')
        :wikitext('[[#'.. ref_link_id  ..'|['.. main_index .. '.' .. sub_cite_index ..']]]')
      :done()
	return tostring(cite_html)
  end

end

function p.render_all(frame)
  local cite_num = v.get('cite_index')
  if empty(cite_num) then
  	return ''
  end
  
  -- todo 改成多模板渲染
  local html = ''
  html = html ..  '<div class="mw-references-wrap"><div class="references">'
  for i = 1, tonumber(cite_num) do
  	mw.log(v.get('list_groups_' .. i))
  	local name =  v.get('cite_idx' .. i)
  	local group = v.get('cite_' .. name .. '.group')
  	if empty(v.get('group_' .. group .. '_i')) then
        -- do notiong 说明之前已经输出过此group了, 或者是sub cite
	else
	  	-- get sub html
	  	local subhtml = ''
	  	if notempty(v.get('cite_' .. tostring(name) .. '.sub_i')) and tonumber(v.get('cite_' .. tostring(name) .. '.sub_i')) then
	  		subhtml = subhtml .. '<div class="sub-cites">'
	  		local sub_count = v.get('cite_' .. tostring(name) .. '.sub_i')
	  		for sub_i = 1, tonumber(sub_count) do
	  			local sub_li_html = mw.html.create()
			      :tag('div'):wikitext('&ensp;&ensp;&ensp;'.. v.get('cite_' .. name .. '.index') .. '.' .. sub_i .. '&ensp;')
			        :tag('span'):addClass('mw-cite-backlink')
			          :wikitext('[[#'.. v.get('cite_' .. name .. '.sub' .. sub_i .. '.cite_link_id') ..'|↑]]&nbsp;')
			          :tag('span'):attr('id', v.get('cite_' .. name .. '.sub' .. sub_i .. '.ref_link_id') )
			        	:tag('span'):addClass('sub-ref-pre'):wikitext(v.get('cite_' .. name .. '.content') .. '&nbsp;'):done()
			        	:tag('span'):addClass('reference-text'):wikitext(v.get('cite_' .. name .. '.sub' .. sub_i .. '.content')):done()
			          :done()
			        :done()
			      :done()
				subhtml = subhtml .. tostring(sub_li_html)
	  		end
	  	    subhtml = subhtml .. '</div>'
	  	end
	  	
	  	local cite_html = mw.html.create()
	      :tag('div'):addClass('ref-item'):wikitext(v.get('cite_' .. name .. '.index') .. '.&nbsp;')
	        :tag('span'):addClass('mw-cite-backlink'):wikitext('[[#'.. v.get('cite_' .. name .. '.cite_link_id') ..'|↑]]'):done()
	        :tag('span'):attr('id', v.get('cite_' .. name .. '.ref_link_id') ):addClass('reference-text'):wikitext(v.get('cite_' .. name .. '.content')):done()
	        :wikitext(subhtml)
	      :done()
		html = html .. tostring(cite_html)
	end
  end
  html = html ..  '</div></div>'
  mw.log(html)
  return html
end


function p.render_group(frame)
  local group = frame.args['group']
  -- 拿到group下所有name
  local name_count = v.get('group_' .. group .. '_i')
  if empty(name_count) then
  	return '没有找到group=' .. group .. '的引用'
  end
  
  v.del('group_' .. group .. '_i') -- 标记该组已完成
  
  -- todo 改成多模板渲染
  local html = ''
  html = html ..  '<div class="mw-references-wrap"><div class="references">'
  for i = 1, tonumber(name_count) do
  	local name = v.get('group_' .. group .. tostring(i))
  	
  	-- get sub html
  	local subhtml = ''
  	if notempty(v.get('cite_' .. tostring(name) .. '.sub_i')) and tonumber(v.get('cite_' .. tostring(name) .. '.sub_i')) then
  		subhtml = subhtml .. '<div class="sub-cites">'
  		local sub_count = v.get('cite_' .. tostring(name) .. '.sub_i')
  		for sub_i = 1, tonumber(sub_count) do
  			local sub_li_html = mw.html.create()
		      :tag('div'):wikitext('&ensp;&ensp;&ensp;'.. v.get('cite_' .. name .. '.index') .. '.' .. sub_i .. '&nbsp;')
		        :tag('span'):addClass('mw-cite-backlink')
		          :wikitext('[[#'.. v.get('cite_' .. name .. '.sub' .. sub_i .. '.cite_link_id') ..'|↑]]&nbsp;')
		          :tag('span'):attr('id', v.get('cite_' .. name .. '.sub' .. sub_i .. '.ref_link_id') )
		        	:tag('span'):addClass('sub-ref-pre'):wikitext(v.get('cite_' .. name .. '.content') .. '&nbsp;'):done()
		        	:tag('span'):addClass('reference-text'):wikitext(v.get('cite_' .. name .. '.sub' .. sub_i .. '.content')):done()
		          :done()
		        :done()
		      :done()
			subhtml = subhtml .. tostring(sub_li_html)
  		end
  	    subhtml = subhtml .. '</div>'
  	end
  	
  	local cite_html = mw.html.create()
      :tag('div'):addClass('ref-item'):wikitext(v.get('cite_' .. name .. '.index') .. '.')
        :tag('span'):addClass('mw-cite-backlink'):wikitext('[[#'.. v.get('cite_' .. name .. '.cite_link_id') ..'|↑]]&nbsp;'):done()
        :tag('span'):attr('id', v.get('cite_' .. name .. '.ref_link_id') ):addClass('reference-text'):wikitext(v.get('cite_' .. name .. '.content')):done()
        :wikitext(subhtml)
      :done()
	html = html .. tostring(cite_html)

  end
  html = html ..  '</div></div>'
  mw.log(html)
  return html
end


return p