모듈:행간주석
이 모듈에 대한 설명문서는 모듈:행간주석/설명문서에서 만들 수 있습니다
local p = {}
local function trim(s)
return s and mw.text.trim(s) or s
end
local function smartSplit(s)
local result = {}
if not s then return result end
local braceDepth = 0 -- {{ }} 깊이
local linkDepth = 0 -- [[ ]] 깊이
local tagDepth = 0 -- < > 깊이 (HTML 태그 안쪽)
local buf = {}
local i = 1
local len = #s
local function inProtected()
return braceDepth > 0 or linkDepth > 0 or tagDepth > 0
end
while i <= len do
local two = s:sub(i, i + 1)
local c = s:sub(i, i)
if two == '{{' then
braceDepth = braceDepth + 1
table.insert(buf, two)
i = i + 2
elseif two == '}}' then
if braceDepth > 0 then braceDepth = braceDepth - 1 end
table.insert(buf, two)
i = i + 2
elseif two == '[[' then
linkDepth = linkDepth + 1
table.insert(buf, two)
i = i + 2
elseif two == ']]' then
if linkDepth > 0 then linkDepth = linkDepth - 1 end
table.insert(buf, two)
i = i + 2
elseif c == '<' and tagDepth == 0 and braceDepth == 0 then
tagDepth = tagDepth + 1
table.insert(buf, c)
i = i + 1
elseif c == '>' and tagDepth > 0 then
tagDepth = tagDepth - 1
table.insert(buf, c)
i = i + 1
else
if c:match('%s') and not inProtected() then
if #buf > 0 then
table.insert(result, table.concat(buf))
buf = {}
end
else
table.insert(buf, c)
end
i = i + 1
end
end
if #buf > 0 then
table.insert(result, table.concat(buf))
end
return result
end
local function looksLikeAbbrev(text)
if not text then return false end
if text:find('{{') or text:find('%[%[') or text:find('<') then return false end
if text:find('%a') and not text:find('%l') then
return true
end
return false
end
local ALIASES = {
orig = { '원어', '原語' },
trans = { '전사', '転写' },
gloss = { '주석', '注釈' },
translation = { '번역', '翻訳' },
source = { '출처', '出典' },
glossstyle = { '주석스타일', '注釈スタイル' },
}
function p.gloss(frame)
local parentArgs = frame:getParent() and frame:getParent().args or {}
local args = frame.args
local function getArg(field, suffix)
suffix = suffix or ''
for _, name in ipairs(ALIASES[field]) do
local key = name .. suffix
local v = args[key]
if v ~= nil and trim(v) ~= '' then return trim(v) end
v = parentArgs[key]
if v ~= nil and trim(v) ~= '' then return trim(v) end
end
return nil
end
local glossStyleOff = (getArg('glossstyle') == '없음' or getArg('glossstyle') == 'なし')
local words = {}
local i = 1
while true do
local w = getArg('orig', i)
local g = getArg('gloss', i)
local t = getArg('trans', i)
if not w and not g then break end
table.insert(words, { orig = w or '', trans = t, gloss = g or '' })
i = i + 1
end
if #words == 0 then
local origs = smartSplit(getArg('orig'))
local transs = smartSplit(getArg('trans'))
local glosses = smartSplit(getArg('gloss'))
for idx, o in ipairs(origs) do
table.insert(words, { orig = o, trans = transs[idx], gloss = glosses[idx] or '' })
end
end
local translation = getArg('translation')
local source = getArg('source')
local container = mw.html.create('div')
:addClass('interlinear-gloss')
:css('display', 'block')
:css('margin', '1rem 0')
:css('line-height', '1.4')
local row = container:tag('div')
:css('display', 'flex')
:css('flex-wrap', 'wrap')
:css('column-gap', '1em')
:css('row-gap', '0.3em')
for _, w in ipairs(words) do
local cell = row:tag('div')
:css('display', 'inline-block')
:css('text-align', 'left')
:css('vertical-align', 'top')
cell:tag('div')
:css('white-space', 'nowrap')
:wikitext(w.orig)
if w.trans and w.trans ~= '' then
cell:tag('div')
:css('font-style', 'italic')
:css('white-space', 'nowrap')
:wikitext(w.trans)
end
local glossCell = cell:tag('div')
:addClass('interlinear-gloss-text')
:css('white-space', 'nowrap')
if not glossStyleOff and looksLikeAbbrev(w.gloss) then
glossCell:css('font-variant', 'small-caps')
end
glossCell:wikitext(w.gloss)
end
if translation then
container:tag('div')
:css('margin-top', '0.4em')
:wikitext('‘' .. translation .. '’')
end
if source then
container:tag('div')
:css('margin-top', '0.2em')
:css('font-size', '90%')
:wikitext(source)
end
return tostring(container)
end
return p