◆少前百科是非盈利性、非官方的少女前线维基百科。
◆如果您发现某些内容错误/空缺,请勇于修正/添加!参与进来其实很容易!点这里 加入少前百科
◆有任何意见、建议、纠错,欢迎在 GFwiki:反馈与建议 提出和讨论。编辑事务讨论QQ群:597764980,微博@GFwiki少前百科
◆To foreigners,You can use twitter to contact us.
Icon Nyto Silver.png

“模块:CharaVoice”的版本间的差异

来自少前百科GFwiki
跳转至: 导航搜索
第7行: 第7行:
 
local names = {}
 
local names = {}
 
local nameMap
 
local nameMap
 +
local audioExt = {}
 +
local audioExists = false
 
local root
 
local root
  
 
local function processText(original)
 
local function processText(original)
 
return mw.text.encode(mw.ustring.gsub(original or '', '<%d*>', '<br>'), '%[')
 
return mw.text.encode(mw.ustring.gsub(original or '', '<%d*>', '<br>'), '%[')
 +
end
 +
 +
local function filepath(frame, filename)
 +
return frame:callParserFunction('filepath', filename)
 
end
 
end
  
第17行: 第23行:
 
root:tag('h2'):wikitext(nameMap[name])
 
root:tag('h2'):wikitext(nameMap[name])
 
end
 
end
 +
local ext = audioExt[name]
 +
local frame = ext and mw.getCurrentFrame()
 
local voiceTable = root:tag('table'):addClass('voiceTable'):attr('data-name', name)
 
local voiceTable = root:tag('table'):addClass('voiceTable'):attr('data-name', name)
 
for _, voice in ipairs(group) do
 
for _, voice in ipairs(group) do
第36行: 第44行:
 
end
 
end
 
end
 
end
tr:tag('td'):attr('data-filename', name .. voice.code)
+
if ext then
 +
audioExists = true
 +
local filename = name .. voice.code .. '_JP.' .. ext
 +
local audioArgs = {icon_width = '36px', src = filepath(frame, filename)}
 +
tr:tag('td'):addClass('voiceTableMedia'):wikitext(frame:callParserFunction('#widget:MiniAudioPlayer', audioArgs))
 +
end
 
end
 
end
 
end
 
end
第61行: 第74行:
 
return
 
return
 
end
 
end
if not voiceGroups[row[1]] then
+
local name = row[1]
voiceGroups[row[1]] = {}
+
if not voiceGroups[name] then
table.insert(names, row[1])
+
voiceGroups[name] = {}
 +
table.insert(names, name)
 +
end
 +
if not audioExt[name] then
 +
local frame = mw.getCurrentFrame()
 +
local filename = string.format('%s_%s_JP', name, row[2])
 +
if filepath(frame, filename .. '.mp3') then
 +
audioExt[name] = 'mp3'
 +
elseif filepath(frame, filename .. '.wav') then
 +
audioExt[name] = 'wav'
 +
end
 
end
 
end
 
if language then
 
if language then
第69行: 第92行:
 
langGroups[language] = {}
 
langGroups[language] = {}
 
end
 
end
if not langGroups[language][row[1]] then
+
if not langGroups[language][name] then
langGroups[language][row[1]] = {}
+
langGroups[language][name] = {}
 
end
 
end
langGroups[language][row[1]][row[2]] = row[3]
+
langGroups[language][name][row[2]] = row[3]
 
else
 
else
 
local voice = cloneTable(charaVoice[row[2]])
 
local voice = cloneTable(charaVoice[row[2]])
 
voice.text = row[3]
 
voice.text = row[3]
table.insert(voiceGroups[row[1]], voice)
+
table.insert(voiceGroups[name], voice)
 
end
 
end
 
end
 
end
第128行: 第151行:
 
renderGroup(group, name)
 
renderGroup(group, name)
 
end
 
end
return tostring(root)
+
local audioPre = audioExists and mw.getCurrentFrame():callParserFunction('#widget:MiniAudioPlayerJS') or ''
 +
return audioPre .. tostring(root)
 
end
 
end
  

2024年4月8日 (一) 02:47的版本

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

local p = {}
local languages = {'jp', 'kr', 'en'}
local args
local charaVoice
local voiceGroups = {}
local langGroups
local names = {}
local nameMap
local audioExt = {}
local audioExists = false
local root

local function processText(original)
	return mw.text.encode(mw.ustring.gsub(original or '', '<%d*>', '<br>'), '%[')
end

local function filepath(frame, filename)
	return frame:callParserFunction('filepath', filename)
end

local function renderGroup(group, name)
	if nameMap and nameMap[name] then
		root:tag('h2'):wikitext(nameMap[name])
	end
	local ext = audioExt[name]
	local frame = ext and mw.getCurrentFrame()
	local voiceTable = root:tag('table'):addClass('voiceTable'):attr('data-name', name)
	for _, voice in ipairs(group) do
		if not group.is_hidden then
			local code = string.sub(voice.code, 2, -4)
			local tr = voiceTable:tag('tr'):addClass('vo-' .. string.lower(code))
			tr:tag('td'):wikitext(voice.name)
			local textCell = tr:tag('td'):addClass('voiceTableContent')
			if langGroups and langGroups.jp and langGroups.jp[name] then
				local text = langGroups.jp[name][code]
				textCell:tag('p'):addClass('voiceTextJP'):attr('lang', 'ja'):wikitext(processText(text))
			end
			textCell:tag('p'):addClass('voiceTextCN'):wikitext(processText(voice.text))
			for i = 2, 3 do
				local lang = languages[i]
				if langGroups and langGroups[lang] and langGroups[lang][name] then
					local text = langGroups[lang][name][code]
					textCell:tag('p'):addClass('voiceText' .. string.upper(lang)):wikitext(processText(text))
				end
			end
			if ext then
				audioExists = true
				local filename = name .. voice.code .. '_JP.' .. ext
				local audioArgs = {icon_width = '36px', src = filepath(frame, filename)}
				tr:tag('td'):addClass('voiceTableMedia'):wikitext(frame:callParserFunction('#widget:MiniAudioPlayer', audioArgs))
			end
		end
	end
end

local function sortVoices(table1, table2)
	if table1.is_skin ~= table2.is_skin then
		return table2.is_skin
	end
	return table1.id < table2.id
end

local function cloneTable(t)
	local c = {}
	for k, v in pairs(t) do
		c[k] = v
	end
	return c
end

local function groupLine(line, language)
	local row = mw.text.split(line, '|', true)
	if not charaVoice[row[2]] then
		return
	end
	local name = row[1]
	if not voiceGroups[name] then
		voiceGroups[name] = {}
		table.insert(names, name)
	end
	if not audioExt[name] then
		local frame = mw.getCurrentFrame()
		local filename = string.format('%s_%s_JP', name, row[2])
		if filepath(frame, filename .. '.mp3') then
			audioExt[name] = 'mp3'
		elseif filepath(frame, filename .. '.wav') then
			audioExt[name] = 'wav'
		end
	end
	if language then
		if not langGroups[language] then
			langGroups[language] = {}
		end
		if not langGroups[language][name] then
			langGroups[language][name] = {}
		end
		langGroups[language][name][row[2]] = row[3]
	else
		local voice = cloneTable(charaVoice[row[2]])
		voice.text = row[3]
		table.insert(voiceGroups[name], voice)
	end
end

local function mapNames()
	nameMap = {}
	local skinData = mw.loadData('模块:Gun info/skin data')
	local substCount = 0
	for _, v in pairs(skinData) do
		local subst = v.substitute_voice
		if subst then
			for i = 2, #names do
				if subst == names[i] then
					nameMap[subst] = v.name
					substCount = substCount + 1
					break
				end
			end
		end
		if substCount == #names - 1 then
			break
		end
	end
end

local function main()
	local lines = mw.text.split(mw.text.trim(args[1]), '\n', true)
	for _, line in ipairs(lines) do
		groupLine(line)
	end
	for _, lang in ipairs(languages) do
		lines = args[lang]
		if lines then
			if not langGroups then
				langGroups = {}
			end
			lines = mw.text.split(lines, '\n', true)
			for _, line in ipairs(lines) do
				groupLine(line, lang)
			end
		end
	end
	root = mw.html.create()
	table.sort(names)
	if #names > 1 then
		mapNames()
	end
	for _, name in ipairs(names) do
		local group = voiceGroups[name]
		table.sort(group, sortVoices)
		renderGroup(group, name)
	end
	local audioPre = audioExists and mw.getCurrentFrame():callParserFunction('#widget:MiniAudioPlayerJS') or ''
	return audioPre .. tostring(root)
end

function p.sangvis(frame)
	charaVoice = mw.loadData('模块:charaVoice/sangvis')
	args = frame.args
	return frame:extensionTag{ name = 'templatestyles', args = { src = '模板:语音/styles.css' } } .. main()
end

function p.gun(frame)
	charaVoice = mw.loadData('模块:charaVoice/gun')
	args = frame.args
	return frame:extensionTag{ name = 'templatestyles', args = { src = '模板:语音/styles.css' } } .. main()
end
return p