모듈:Style: 두 판 사이의 차이
태그: 편집 취소 |
편집 요약 없음 |
||
| 1번째 줄: | 1번째 줄: | ||
local p = {} | local p = {} | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- | -- 유틸: frame args 병합 | ||
-------------------------------------------------------- | |||
local function getArgs(frame) | |||
local args = {} | |||
local parent = frame:getParent() | |||
if parent then | |||
for k, v in pairs(parent.args) do | |||
if v ~= nil and v ~= "" then | |||
args[k] = v | |||
end | |||
end | |||
end | |||
for k, v in pairs(frame.args) do | |||
if v ~= nil and v ~= "" then | |||
args[k] = v | |||
end | |||
end | |||
return args | |||
end | |||
-------------------------------------------------------- | |||
-- $xxx → var(--xxx) | |||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local function convertValue(val) | local function convertValue(val) | ||
| 17번째 줄: | 37번째 줄: | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local mapSingle = { | local mapSingle = { | ||
c = "color", | -- 색/텍스트 | ||
c = "color", | |||
bg = "background", | bg = "background", | ||
bgc = "background-color", | bgc = "background-color", | ||
| 27번째 줄: | 48번째 줄: | ||
ta = "text-align", | ta = "text-align", | ||
-- 박스 크기 | |||
w = "width", | w = "width", | ||
h = "height", | h = "height", | ||
| 32번째 줄: | 54번째 줄: | ||
minw = "min-width", | minw = "min-width", | ||
-- 패딩 | |||
p = "padding", | p = "padding", | ||
pt = "padding-top", | pt = "padding-top", | ||
| 38번째 줄: | 61번째 줄: | ||
pl = "padding-left", | pl = "padding-left", | ||
-- 마진 | |||
m = "margin", | m = "margin", | ||
mt = "margin-top", | mt = "margin-top", | ||
| 53번째 줄: | 77번째 줄: | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- border | -- border | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local borderMap = { | local borderMap = { | ||
| 63번째 줄: | 87번째 줄: | ||
} | } | ||
local borderTypeMap = { | local borderTypeMap = { | ||
sld = "solid", | sld = "solid", | ||
| 84번째 줄: | 105번째 줄: | ||
end | end | ||
local function buildBorder(token, cssName, styles) | local function buildBorder(token, cssName, styles) | ||
-- token 예: "bd-1px-sld-$borderColor" | -- token 예: "bd-1px-sld-$borderColor" | ||
local parts = mw.text.split(token, "-") | local parts = mw.text.split(token, "-") | ||
table.remove(parts, 1) -- bd / bdt / | table.remove(parts, 1) -- bd / bdt / ... | ||
local result = {} | local result = {} | ||
for _, part in ipairs(parts) do | for _, part in ipairs(parts) do | ||
if borderTypeMap[part] then | if borderTypeMap[part] then | ||
| 106번째 줄: | 123번째 줄: | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- 공통 파서: 스타일 | -- 공통 파서: 스타일 + colspan/rowspan | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local function parseSpec(spec) | local function parseSpec(spec) | ||
| 120번째 줄: | 137번째 줄: | ||
local val = token:sub(dashPos + 1) | local val = token:sub(dashPos + 1) | ||
-- padding/margin 축약 | -- padding/margin 축약 | ||
if key == "px" then | if key == "px" then | ||
val = convertValue(val) | val = convertValue(val) | ||
| 138번째 줄: | 155번째 줄: | ||
addStyle(styles, "margin-bottom", val) | addStyle(styles, "margin-bottom", val) | ||
-- border | -- border | ||
elseif borderMap[key] then | elseif borderMap[key] then | ||
buildBorder(token, borderMap[key], styles) | buildBorder(token, borderMap[key], styles) | ||
-- colspan/rowspan (col-3, row-2 | -- colspan/rowspan (col-3, row-2 만 사용) | ||
elseif key == "col" then | elseif key == "col" then | ||
colspan = val | colspan = val | ||
| 148번째 줄: | 165번째 줄: | ||
rowspan = val | rowspan = val | ||
-- 일반 | -- 일반 속성 | ||
else | else | ||
local cssName = mapSingle[key] | local cssName = mapSingle[key] | ||
| 164번째 줄: | 181번째 줄: | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- 1) | -- 1) 속성 전체(attr): style + colspan/rowspan | ||
-- {{스타일|...}} 이 이 함수를 쓰게 할 것. | |||
-------------------------------------------------------- | -------------------------------------------------------- | ||
function p. | function p.attr(frame) | ||
local args = | local args = getArgs(frame) | ||
local spec = mw.text.trim(args[1] or "") | |||
local spec = args[1] or "" | |||
if spec == "" then return "" end | if spec == "" then return "" end | ||
local css = parseSpec(spec) | local css, cToken, rToken = parseSpec(spec) | ||
local | -- 명시 파라미터(col=, row=)도 허용 | ||
local colspan = args.col or cToken | |||
local rowspan = args.row or rToken | |||
local attrs = {} | local attrs = {} | ||
| 216번째 줄: | 208번째 줄: | ||
return table.concat(attrs, " ") | return table.concat(attrs, " ") | ||
end | |||
-------------------------------------------------------- | |||
-- 2) CSS 문자열만 필요할 때(예전 방식 유지용) | |||
-- <div style="{{스타일CSS|...}}"> | |||
-------------------------------------------------------- | |||
function p.css(frame) | |||
local args = getArgs(frame) | |||
local spec = mw.text.trim(args[1] or "") | |||
if spec == "" then return "" end | |||
local css = parseSpec(spec) | |||
return css | |||
end | end | ||
return p | return p | ||
2025년 11월 29일 (토) 17:38 판
이 모듈에 대한 설명문서는 모듈:Style/설명문서에서 만들 수 있습니다
local p = {}
--------------------------------------------------------
-- 유틸: frame args 병합
--------------------------------------------------------
local function getArgs(frame)
local args = {}
local parent = frame:getParent()
if parent then
for k, v in pairs(parent.args) do
if v ~= nil and v ~= "" then
args[k] = v
end
end
end
for k, v in pairs(frame.args) do
if v ~= nil and v ~= "" then
args[k] = v
end
end
return args
end
--------------------------------------------------------
-- $xxx → var(--xxx)
--------------------------------------------------------
local function convertValue(val)
if not val then return val end
if mw.ustring.sub(val, 1, 1) == "$" then
val = "var(--" .. mw.ustring.sub(val, 2) .. ")"
end
return val
end
--------------------------------------------------------
-- 단일 속성 매핑
--------------------------------------------------------
local mapSingle = {
-- 색/텍스트
c = "color",
bg = "background",
bgc = "background-color",
fs = "font-size",
fw = "font-weight",
ff = "font-family",
lh = "line-height",
ls = "letter-spacing",
ta = "text-align",
-- 박스 크기
w = "width",
h = "height",
maxw = "max-width",
minw = "min-width",
-- 패딩
p = "padding",
pt = "padding-top",
pr = "padding-right",
pb = "padding-bottom",
pl = "padding-left",
-- 마진
m = "margin",
mt = "margin-top",
mr = "margin-right",
mb = "margin-bottom",
ml = "margin-left",
ovf = "overflow",
ovfx = "overflow-x",
ovfy = "overflow-y",
dsp = "display",
pos = "position",
zi = "z-index",
}
--------------------------------------------------------
-- border
--------------------------------------------------------
local borderMap = {
bd = "border",
bdt = "border-top",
bdr = "border-right",
bdb = "border-bottom",
bdl = "border-left",
}
local borderTypeMap = {
sld = "solid",
dsh = "dashed",
dot = "dotted",
db = "double",
grv = "groove",
rdg = "ridge",
ins = "inset",
ous = "outset",
}
local function addStyle(list, name, value)
if not name or name == "" then return end
if not value or value == "" then return end
value = convertValue(value)
table.insert(list, name .. ":" .. value .. ";")
end
local function buildBorder(token, cssName, styles)
-- token 예: "bd-1px-sld-$borderColor"
local parts = mw.text.split(token, "-")
table.remove(parts, 1) -- bd / bdt / ...
local result = {}
for _, part in ipairs(parts) do
if borderTypeMap[part] then
table.insert(result, borderTypeMap[part])
else
table.insert(result, convertValue(part))
end
end
addStyle(styles, cssName, table.concat(result, " "))
end
--------------------------------------------------------
-- 공통 파서: 스타일 + colspan/rowspan
--------------------------------------------------------
local function parseSpec(spec)
local styles = {}
local colspan, rowspan
for _, token in ipairs(mw.text.split(spec, "%s+")) do
token = mw.text.trim(token)
if token ~= "" then
local dashPos = token:find("-")
if dashPos then
local key = token:sub(1, dashPos - 1)
local val = token:sub(dashPos + 1)
-- padding/margin 축약
if key == "px" then
val = convertValue(val)
addStyle(styles, "padding-left", val)
addStyle(styles, "padding-right", val)
elseif key == "py" then
val = convertValue(val)
addStyle(styles, "padding-top", val)
addStyle(styles, "padding-bottom", val)
elseif key == "mx" then
val = convertValue(val)
addStyle(styles, "margin-left", val)
addStyle(styles, "margin-right", val)
elseif key == "my" then
val = convertValue(val)
addStyle(styles, "margin-top", val)
addStyle(styles, "margin-bottom", val)
-- border
elseif borderMap[key] then
buildBorder(token, borderMap[key], styles)
-- colspan/rowspan (col-3, row-2 만 사용)
elseif key == "col" then
colspan = val
elseif key == "row" then
rowspan = val
-- 일반 속성
else
local cssName = mapSingle[key]
if cssName then
val = convertValue(val)
addStyle(styles, cssName, val)
end
end
end
end
end
return table.concat(styles, " "), colspan, rowspan
end
--------------------------------------------------------
-- 1) 속성 전체(attr): style + colspan/rowspan
-- {{스타일|...}} 이 이 함수를 쓰게 할 것.
--------------------------------------------------------
function p.attr(frame)
local args = getArgs(frame)
local spec = mw.text.trim(args[1] or "")
if spec == "" then return "" end
local css, cToken, rToken = parseSpec(spec)
-- 명시 파라미터(col=, row=)도 허용
local colspan = args.col or cToken
local rowspan = args.row or rToken
local attrs = {}
if css ~= "" then
table.insert(attrs, 'style="' .. css .. '"')
end
if colspan and colspan ~= "" then
table.insert(attrs, 'colspan="' .. colspan .. '"')
end
if rowspan and rowspan ~= "" then
table.insert(attrs, 'rowspan="' .. rowspan .. '"')
end
return table.concat(attrs, " ")
end
--------------------------------------------------------
-- 2) CSS 문자열만 필요할 때(예전 방식 유지용)
-- <div style="{{스타일CSS|...}}">
--------------------------------------------------------
function p.css(frame)
local args = getArgs(frame)
local spec = mw.text.trim(args[1] or "")
if spec == "" then return "" end
local css = parseSpec(spec)
return css
end
return p