← 모듈:푸른 저편의 포리듬/ 캐릭터 프로필문서 편집 권한이 없습니다. 다음 이유를 확인해주세요: 요청한 명령은 다음 권한을 가진 사용자에게 제한됩니다: 사용자. 문서의 원본을 보거나 복사할 수 있습니다. 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 -- 이미지 블록 (VN 먼저, 애니 다음). 파일명은 그대로 사용. local function build_image_block(args) local images = {} if args['이미지_VN'] and args['이미지_VN'] ~= '' then table.insert(images, { title = "비주얼 노벨", file = trim(args['이미지_VN']) }) end if args['이미지_애니'] and args['이미지_애니'] ~= '' then table.insert(images, { title = "애니메이션", file = trim(args['이미지_애니']) }) end if args['이미지_추가'] and args['이미지_추가'] ~= '' then for img in string.gmatch(args['이미지_추가'], '([^,]+)') do img = trim(img) if img ~= '' then table.insert(images, { title = "추가", file = img }) end end end -- 이미지를 감싸는 위키텍스트 생성 if #images == 0 then return '[[파일:NoImage.png|200px]]' elseif #images == 1 then return string.format('[[파일:%s|200px]]', mw.text.encode(images[1].file)) else local t = {} table.insert(t, '<tabber>') for i, im in ipairs(images) do local title = mw.text.escape(im.title) local file = mw.text.encode(im.file) table.insert(t, string.format('%s= [[파일:%s|200px]]', title, file)) if i < #images then table.insert(t, '|-|') end end table.insert(t, '</tabber>') return table.concat(t, '\n') 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 = {} -- HTML 코드를 Lua에서 직접 생성하지 않고, 위키텍스트 문자열로 반환 if kr ~= '' then table.insert(parts, string.format('<div class="prf-name-kr">%s</div>', 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('<div class="prf-name-sub">%s</div>', second)) end return table.concat(parts, '\n') end -- 라벨+값 행 생성 (값 없으면 빈 문자열) local function row(label, value) if not value or value == '' then return '' end -- 이 함수는 HTML 문자열을 반환 return string.format('<div class="prf-row"><strong>%s</strong> %s</div>', mw.text.escape(label), mw.text.escape(value)) end -- 나이 출력 규칙: VN 먼저, 애니 다음 local function build_age_row(args) local nv = trim(args['나이_VN']) local na = trim(args['나이_애니']) -- 이 함수는 HTML 문자열을 반환 if nv ~= '' and na ~= '' then return string.format('<div class="prf-row"><strong>나이</strong> VN %s / 애니 %s</div>', mw.text.escape(nv), mw.text.escape(na)) elseif nv ~= '' then return string.format('<div class="prf-row"><strong>나이</strong> VN %s</div>', mw.text.escape(nv)) elseif na ~= '' then return string.format('<div class="prf-row"><strong>나이</strong> 애니 %s</div>', mw.text.escape(na)) else return '' end end -- 메인 생성 함수 (ASCII 식별자 사용: "main") function p.main(frame) local parent = frame:getParent() or frame local args = parent.args or {} -- frame이 유효하지 않으면 에러 방지 if not frame.preprocess then return "스크립트 오류: Frame 객체가 유효하지 않습니다." end for k, v in pairs(args) do args[k] = trim(v) end local theme = args['색상'] and args['색상'] ~= '' and args['색상'] or '#4cc9ff' local image_block = build_image_block(args) local name_block = build_name_block(args) -- 기본 정보 local basic = '' basic = basic .. row('성별', args['성별']) basic = basic .. build_age_row(args) basic = basic .. row('생일', args['생일']) basic = basic .. row('신장', args['신장']) basic = basic .. row('체중', args['체중']) basic = basic .. row('머리색', args['머리색']) basic = basic .. row('눈색', args['눈색']) -- FC 프로필 local fc = '' fc = fc .. row('포지션', args['포지션']) fc = fc .. row('소속 팀', args['소속_팀']) local techs = gather_techs(args) if #techs > 0 then local tstr = '<div class="prf-row"><strong>시그니처 기술</strong><ol class="sig-list">' for _, tname in ipairs(techs) do tstr = tstr .. string.format('<li>%s</li>', mw.text.escape(tname)) end tstr = tstr .. '</ol></div>' fc = fc .. tstr end -- 개인정보 (학교는 개인정보 안에) local personal = '' personal = personal .. row('학교', args['학교']) personal = personal .. row('거주지', args['거주지']) personal = personal .. row('취미', args['취미']) personal = personal .. row('좋아하는 음식', args['좋아하는음식']) -- 성우 local voice = '' voice = voice .. row('일본어', args['성우_JP']) voice = voice .. row('영어', args['성우_EN']) -- 데뷔 local debut = '' debut = debut .. row('애니메이션', args['애니_데뷔']) debut = debut .. row('게임(VN)', args['게임_데뷔']) debut = debut .. row('만화', args['만화_데뷔']) -- HTML 구성 local html = mw.html.create() html:tag('div'):addClass('prf-card'):cssText('display:flex;gap:14px;border-radius:10px;padding:12px;align-items:flex-start;'):done() -- 좌측 이미지 (frame:preprocess 사용으로 wikitext 에러 해결) local left = mw.html.create('div'):addClass('prf-left'):cssText('flex:0 0 36%;min-width:200px;') left:node(frame:preprocess(image_block)) html:node(left) -- 우측 (모든 wikitext는 frame:preprocess로 처리) local right = mw.html.create('div'):addClass('prf-right'):cssText('flex:1 1 auto;') -- 이름 블록 right:tag('div'):addClass('prf-name'):node(frame:preprocess(name_block)):done() -- 섹션별 정보 if basic ~= '' then right:tag('div'):addClass('prf-section'):tag('h4'):text('기본 정보'):done() right:node(frame:preprocess(basic)) end if fc ~= '' then right:tag('div'):addClass('prf-section'):tag('h4'):text('FC 프로필'):done() right:node(frame:preprocess(fc)) end if personal ~= '' then right:tag('div'):addClass('prf-section'):tag('h4'):text('개인 정보'):done() right:node(frame:preprocess(personal)) end if voice ~= '' then right:tag('div'):addClass('prf-section'):tag('h4'):text('성우'):done() right:node(frame:preprocess(voice)) end if debut ~= '' then right:tag('div'):addClass('prf-section'):tag('h4'):text('데뷔'):done() right:node(frame:preprocess(debut)) end html:node(right) -- 인라인 CSS (반응형 포함) - 테마 색상 적용 local style = string.format([[<style>.prf-card { border:2px solid %s; background:#ffffff; }.prf-name-kr { font-size:1.25em; font-weight:700; color:%s; margin-bottom:4px; }.prf-name-sub { font-size:0.95em; color:#444; margin-bottom:8px; }.prf-row { margin:4px 0; }.prf-section h4 { margin:8px 0 6px 0; color:%s; font-size:0.95em; }.sig-list { margin:4px 0 0 18px; padding:0; }.tabber { margin-bottom:8px; }@media screen and (max-width:768px) { .prf-card { flex-direction:column; } .prf-left { width:100%%; min-width:0; }}</style>]], theme, theme, theme) -- 최종 출력: 스타일 + HTML 객체 return style .. tostring(html) end return p 이 문서에서 사용한 틀: 모듈:푸른 저편의 포리듬/ 캐릭터 프로필/설명문서 (원본 보기) 모듈:푸른 저편의 포리듬/ 캐릭터 프로필 문서로 돌아갑니다.