편집 요약 없음 |
편집 요약 없음 |
||
| 21번째 줄: | 21번째 줄: | ||
end | end | ||
-- 이미지 블록 ( | -- 이미지 블록 (탭 기능을 표준 위키텍스트로 반환) | ||
local function build_image_block(args) | local function build_image_block(args) | ||
local images = {} | local images = {} | ||
if args['이미지_VN'] and args['이미지_VN'] ~= '' then | if args['이미지_VN'] and args['이미지_VN'] ~= '' then | ||
table.insert(images, { title = " | table.insert(images, { title = "VN", file = trim(args['이미지_VN']) }) | ||
end | end | ||
if args['이미지_애니'] and args['이미지_애니'] ~= '' then | if args['이미지_애니'] and args['이미지_애니'] ~= '' then | ||
table.insert(images, { title = " | table.insert(images, { title = "애니", file = trim(args['이미지_애니']) }) | ||
end | end | ||
-- 추가 이미지는 생략 (탭 충돌 방지) | |||
if #images == 0 then | if #images == 0 then | ||
return '[[파일:NoImage.png| | return '[[파일:NoImage.png|250px|center]]' | ||
elseif #images == 1 then | elseif #images == 1 then | ||
return string.format('[[파일:%s| | return string.format('[[파일:%s|250px|center]]', mw.text.encode(images[1].file)) | ||
else | else | ||
-- 탭 대신 간단한 이미지 갤러리 또는 첫 번째 이미지 사용 (가장 안전) | |||
return string.format('[[파일:%s|250px|center]]<div style="font-size:80%%;text-align:center;">(VN/애니 버전 전환은 갤러리/탭 구현 필요)</div>', mw.text.encode(images[1].file)) | |||
end | end | ||
end | end | ||
-- 이름 블록 | -- 이름 블록 (표 셀용으로 간단히 변환) | ||
local function build_name_block(args) | local function build_name_block(args) | ||
local kr = trim(args['이름'] or '') | local kr = trim(args['이름'] or '') | ||
| 63번째 줄: | 48번째 줄: | ||
local en = trim(args['이름_영어'] or '') | local en = trim(args['이름_영어'] or '') | ||
local parts = {} | local parts = {} | ||
if kr ~= '' then table.insert(parts, string.format('< | if kr ~= '' then table.insert(parts, string.format('<strong>%s</strong>', mw.text.escape(kr))) end | ||
if jp ~= '' or en ~= '' then | if jp ~= '' or en ~= '' then | ||
local second = '' | local second = '' | ||
| 71번째 줄: | 56번째 줄: | ||
second = mw.text.escape((jp ~= '' and jp) or en) | second = mw.text.escape((jp ~= '' and jp) or en) | ||
end | end | ||
table.insert(parts, string.format('< | table.insert(parts, string.format('<br/><span style="font-size:90%%;">(%s)</span>', second)) | ||
end | end | ||
return table.concat(parts, '\n') | return table.concat(parts, '\n') | ||
end | end | ||
-- 라벨+값 행 생성 ( | -- 라벨+값 행 생성 (표의 행) | ||
local function | local function table_row(label, value, is_header) | ||
if not value or value == '' then return '' end | if not value or value == '' then return '' end | ||
return string.format(' | local tag = is_header and '!' or '|' | ||
return string.format('|- \n|%s style="width: 30%%; background-color: #f2f2f2; padding: 5px;" | %s \n|%s style="padding: 5px;" | %s', tag, mw.text.escape(label), tag, mw.text.escape(value)) | |||
end | end | ||
-- 나이 출력 규칙 | -- 나이 출력 규칙 (표의 행) | ||
local function build_age_row(args) | local function build_age_row(args) | ||
local nv = trim(args['나이_VN']) | local nv = trim(args['나이_VN']) | ||
local na = trim(args['나이_애니']) | local na = trim(args['나이_애니']) | ||
if nv ~= '' and na ~= '' then | if nv ~= '' and na ~= '' then | ||
return | return table_row('나이', 'VN ' .. nv .. ' / 애니 ' .. na) | ||
elseif nv ~= '' then | elseif nv ~= '' then | ||
return | return table_row('나이', 'VN ' .. nv) | ||
elseif na ~= '' then | elseif na ~= '' then | ||
return | return table_row('나이', '애니 ' .. na) | ||
else | else | ||
return '' | return '' | ||
| 97번째 줄: | 83번째 줄: | ||
end | end | ||
-- 메인 생성 함수 ( | -- 메인 생성 함수 (순수 위키텍스트 반환) | ||
function p.main(frame) | function p.main(frame) | ||
local parent = frame:getParent() or frame | local parent = frame:getParent() or frame | ||
local args = parent.args or {} | local args = parent.args or {} | ||
for k, v in pairs(args) do args[k] = trim(v) end | for k, v in pairs(args) do args[k] = trim(v) end | ||
local | local theme_color = args['색상'] and args['색상'] ~= '' and args['색상'] or '#007bff' | ||
-- ********** 위키 테이블 문자열 구성 시작 ********** | |||
local wiki_table = {} | |||
-- | -- 외부 테이블 시작 (표준 인포박스 스타일) | ||
table.insert(wiki_table, string.format('{| class="infobox" style="width: 300px; margin: 0 0 1em 1em; border: 1px solid #aaa; border-collapse: collapse; background-color: #f9f9f9; float: right; font-size: 90%%;"')) | |||
-- | -- 1. 제목 및 이미지 | ||
table.insert(wiki_table, string.format('! colspan="2" style="background-color: %s; color: white; padding: 5px; text-align: center; font-size: 110%%;" | %s 프로필', theme_color, args['이름'] or '')) | |||
table.insert(wiki_table, '|-') | |||
table.insert(wiki_table, string.format('| colspan="2" style="padding: 10px; text-align: center;" | %s', build_image_block(args))) | |||
-- | -- 2. 이름 정보 (이름 블록을 하나의 셀로 처리) | ||
table.insert(wiki_table, '|-') | |||
table.insert(wiki_table, string.format('| colspan="2" style="text-align: center; padding: 5px;" | %s', build_name_block(args))) | |||
-- | -- 3. 기본 정보 | ||
table.insert(wiki_table, '|-') | |||
table.insert(wiki_table, string.format('! colspan="2" style="background-color: #e0e0e0; padding: 5px; text-align: center;" | 기본 정보')) | |||
table.insert(wiki_table, build_age_row(args)) | |||
table.insert(wiki_table, table_row('성별', args['성별'])) | |||
table.insert(wiki_table, table_row('생일', args['생일'])) | |||
table.insert(wiki_table, table_row('신장', args['신장'])) | |||
table.insert(wiki_table, table_row('체중', args['체중'])) | |||
table.insert(wiki_table, table_row('머리색', args['머리색'])) | |||
table.insert(wiki_table, table_row('눈색', args['눈색'])) | |||
table.insert(wiki_table, table_row('학교', args['학교'])) | |||
table.insert(wiki_table, table_row('거주지', args['거주지'])) | |||
-- 4. FC 프로필 | |||
local fc_content = table_row('포지션', args['포지션']) .. table_row('소속 팀', args['소속_팀']) | |||
local techs = gather_techs(args) | local techs = gather_techs(args) | ||
if #techs > 0 then | if #techs > 0 then | ||
fc_content = fc_content .. table_row('시그니처 기술', table.concat(techs, '<br/>')) | |||
end | |||
if trim(args['포지션']) ~= '' or trim(args['소속_팀']) ~= '' or #techs > 0 then | |||
table.insert(wiki_table, '|-') | |||
table.insert(wiki_table, string.format('! colspan="2" style="background-color: #a0d0ff; padding: 5px; text-align: center;" | FC 프로필')) | |||
table.insert(wiki_table, fc_content) | |||
end | end | ||
-- | -- 5. 성우 및 데뷔 | ||
if trim(args['성우_JP']) ~= '' or trim(args['성우_EN']) ~= '' then | |||
table.insert(wiki_table, '|-') | |||
table.insert(wiki_table, string.format('! colspan="2" style="background-color: #e0e0e0; padding: 5px; text-align: center;" | 성우 정보')) | |||
table.insert(wiki_table, table_row('일본어', args['성우_JP'])) | |||
table.insert(wiki_table, table_row('영어', args['성우_EN'])) | |||
end | end | ||
table.insert(wiki_table, '|}') -- 테이블 닫기 | |||
-- 최종 출력: 스타일 태그가 없으므로 Lua 모듈은 순수한 위키텍스트를 반환함. | |||
return table.concat(wiki_table, '\n') | |||
-- 최종 출력: 스타일 | |||
return | |||
end | end | ||
return p | return p | ||
2025년 12월 5일 (금) 02:57 판
이 모듈에 대한 설명문서는 모듈:푸른 저편의 포리듬/ 캐릭터 프로필/설명문서에서 만들 수 있습니다
local p = {}
local mw = mw
local tt = mw.text
-- 안전 문자열 트림
local function trim(s)
if not s then return '' end
return tt.trim(tostring(s))
end
-- 시그니처 기술 수집 (시그니처기술1..10)
local function gather_techs(args)
local techs = {}
for i = 1, 10 do
local k = '시그니처기술' .. i
if args[k] and args[k] ~= '' then
table.insert(techs, trim(args[k]))
end
end
return techs
end
-- 이미지 블록 (탭 기능을 표준 위키텍스트로 반환)
local function build_image_block(args)
local images = {}
if args['이미지_VN'] and args['이미지_VN'] ~= '' then
table.insert(images, { title = "VN", file = trim(args['이미지_VN']) })
end
if args['이미지_애니'] and args['이미지_애니'] ~= '' then
table.insert(images, { title = "애니", file = trim(args['이미지_애니']) })
end
-- 추가 이미지는 생략 (탭 충돌 방지)
if #images == 0 then
return '[[파일:NoImage.png|250px|center]]'
elseif #images == 1 then
return string.format('[[파일:%s|250px|center]]', mw.text.encode(images[1].file))
else
-- 탭 대신 간단한 이미지 갤러리 또는 첫 번째 이미지 사용 (가장 안전)
return string.format('[[파일:%s|250px|center]]<div style="font-size:80%%;text-align:center;">(VN/애니 버전 전환은 갤러리/탭 구현 필요)</div>', mw.text.encode(images[1].file))
end
end
-- 이름 블록 (표 셀용으로 간단히 변환)
local function build_name_block(args)
local kr = trim(args['이름'] or '')
local jp = trim(args['이름_일어'] or '')
local en = trim(args['이름_영어'] or '')
local parts = {}
if kr ~= '' then table.insert(parts, string.format('<strong>%s</strong>', mw.text.escape(kr))) end
if jp ~= '' or en ~= '' then
local second = ''
if jp ~= '' and en ~= '' then
second = mw.text.escape(jp) .. ' / ' .. mw.text.escape(en)
else
second = mw.text.escape((jp ~= '' and jp) or en)
end
table.insert(parts, string.format('<br/><span style="font-size:90%%;">(%s)</span>', second))
end
return table.concat(parts, '\n')
end
-- 라벨+값 행 생성 (표의 행)
local function table_row(label, value, is_header)
if not value or value == '' then return '' end
local tag = is_header and '!' or '|'
return string.format('|- \n|%s style="width: 30%%; background-color: #f2f2f2; padding: 5px;" | %s \n|%s style="padding: 5px;" | %s', tag, mw.text.escape(label), tag, mw.text.escape(value))
end
-- 나이 출력 규칙 (표의 행)
local function build_age_row(args)
local nv = trim(args['나이_VN'])
local na = trim(args['나이_애니'])
if nv ~= '' and na ~= '' then
return table_row('나이', 'VN ' .. nv .. ' / 애니 ' .. na)
elseif nv ~= '' then
return table_row('나이', 'VN ' .. nv)
elseif na ~= '' then
return table_row('나이', '애니 ' .. na)
else
return ''
end
end
-- 메인 생성 함수 (순수 위키텍스트 반환)
function p.main(frame)
local parent = frame:getParent() or frame
local args = parent.args or {}
for k, v in pairs(args) do args[k] = trim(v) end
local theme_color = args['색상'] and args['색상'] ~= '' and args['색상'] or '#007bff'
-- ********** 위키 테이블 문자열 구성 시작 **********
local wiki_table = {}
-- 외부 테이블 시작 (표준 인포박스 스타일)
table.insert(wiki_table, string.format('{| class="infobox" style="width: 300px; margin: 0 0 1em 1em; border: 1px solid #aaa; border-collapse: collapse; background-color: #f9f9f9; float: right; font-size: 90%%;"'))
-- 1. 제목 및 이미지
table.insert(wiki_table, string.format('! colspan="2" style="background-color: %s; color: white; padding: 5px; text-align: center; font-size: 110%%;" | %s 프로필', theme_color, args['이름'] or ''))
table.insert(wiki_table, '|-')
table.insert(wiki_table, string.format('| colspan="2" style="padding: 10px; text-align: center;" | %s', build_image_block(args)))
-- 2. 이름 정보 (이름 블록을 하나의 셀로 처리)
table.insert(wiki_table, '|-')
table.insert(wiki_table, string.format('| colspan="2" style="text-align: center; padding: 5px;" | %s', build_name_block(args)))
-- 3. 기본 정보
table.insert(wiki_table, '|-')
table.insert(wiki_table, string.format('! colspan="2" style="background-color: #e0e0e0; padding: 5px; text-align: center;" | 기본 정보'))
table.insert(wiki_table, build_age_row(args))
table.insert(wiki_table, table_row('성별', args['성별']))
table.insert(wiki_table, table_row('생일', args['생일']))
table.insert(wiki_table, table_row('신장', args['신장']))
table.insert(wiki_table, table_row('체중', args['체중']))
table.insert(wiki_table, table_row('머리색', args['머리색']))
table.insert(wiki_table, table_row('눈색', args['눈색']))
table.insert(wiki_table, table_row('학교', args['학교']))
table.insert(wiki_table, table_row('거주지', args['거주지']))
-- 4. FC 프로필
local fc_content = table_row('포지션', args['포지션']) .. table_row('소속 팀', args['소속_팀'])
local techs = gather_techs(args)
if #techs > 0 then
fc_content = fc_content .. table_row('시그니처 기술', table.concat(techs, '<br/>'))
end
if trim(args['포지션']) ~= '' or trim(args['소속_팀']) ~= '' or #techs > 0 then
table.insert(wiki_table, '|-')
table.insert(wiki_table, string.format('! colspan="2" style="background-color: #a0d0ff; padding: 5px; text-align: center;" | FC 프로필'))
table.insert(wiki_table, fc_content)
end
-- 5. 성우 및 데뷔
if trim(args['성우_JP']) ~= '' or trim(args['성우_EN']) ~= '' then
table.insert(wiki_table, '|-')
table.insert(wiki_table, string.format('! colspan="2" style="background-color: #e0e0e0; padding: 5px; text-align: center;" | 성우 정보'))
table.insert(wiki_table, table_row('일본어', args['성우_JP']))
table.insert(wiki_table, table_row('영어', args['성우_EN']))
end
table.insert(wiki_table, '|}') -- 테이블 닫기
-- 최종 출력: 스타일 태그가 없으므로 Lua 모듈은 순수한 위키텍스트를 반환함.
return table.concat(wiki_table, '\n')
end
return p