모듈:Style: 두 판 사이의 차이
편집 요약 없음 |
편집 요약 없음 |
||
| (같은 사용자의 중간 판 13개는 보이지 않습니다) | |||
| 1번째 줄: | 1번째 줄: | ||
local currentFrame | |||
local HSL = require('Module:HSL') | |||
local HSL2 = require('Module:HSL2') | |||
local p = {} | local p = {} | ||
function p.attr(frame) | |||
currentFrame = frame | |||
end | |||
function p.css(frame) | |||
currentFrame = frame | |||
end | |||
local function getArgs(frame) | local function getArgs(frame) | ||
local args = {} | local args = {} | ||
| 22번째 줄: | 34번째 줄: | ||
end | end | ||
local function callHSL(moduleName, hex) | |||
if not currentFrame then | |||
return hex | |||
local function convertValue(val) | end | ||
local r, g, b = hexToRGB(hex) | |||
return currentFrame:callParserFunction( | |||
'#invoke', | |||
moduleName, | |||
'main', | |||
'1=' .. hex, -- ⭐ 이게 핵심 | |||
'r=' .. r, | |||
'g=' .. g, | |||
'b=' .. b | |||
) | |||
end | |||
local function convertValue(val, isBackground) | |||
if not val then return val end | if not val then return val end | ||
val = mw.text.trim(val) | |||
-- <...> 벗기기 | |||
if mw.ustring.sub(val, 1, 1) == "<" | if mw.ustring.sub(val, 1, 1) == "<" | ||
and mw.ustring.sub(val, -1) == ">" then | and mw.ustring.sub(val, -1) == ">" then | ||
val = mw.ustring.sub(val, 2, -2) | val = mw.text.trim(mw.ustring.sub(val, 2, -2)) | ||
end | end | ||
-- CSS 변수 | |||
if mw.ustring.sub(val, 1, 1) == "$" then | if mw.ustring.sub(val, 1, 1) == "$" then | ||
return "var(--" .. mw.ustring.sub(val, 2) .. ")" | return "var(--" .. mw.ustring.sub(val, 2) .. ")" | ||
end | end | ||
if mw.ustring.match(val, "^##[%x%X][%x%X][%x%X][%x%X][%x%X][%x%X]$") then | |||
local hex = "#" .. mw.ustring.sub(val, 3) | |||
if isBackground then | |||
return "light-dark(" .. hex .. ", " .. HSL.main{ [1] = hex } .. ")" | |||
else | |||
return "light-dark(" .. hex .. ", " .. HSL2.main{ [1] = hex } .. ")" | |||
end | |||
end | |||
return val | return val | ||
| 41번째 줄: | 84번째 줄: | ||
local mapSingle = { | local mapSingle = { | ||
c = "color", | c = "color", | ||
bg = "background", | bg = "background", | ||
| 59번째 줄: | 98번째 줄: | ||
op = "opacity", | op = "opacity", | ||
w = "width", | w = "width", | ||
h = "height", | h = "height", | ||
| 66번째 줄: | 104번째 줄: | ||
fl = "float", | fl = "float", | ||
p = "padding", | p = "padding", | ||
pt = "padding-top", | pt = "padding-top", | ||
| 73번째 줄: | 110번째 줄: | ||
pl = "padding-left", | pl = "padding-left", | ||
m = "margin", | m = "margin", | ||
mt = "margin-top", | mt = "margin-top", | ||
| 91번째 줄: | 127번째 줄: | ||
} | } | ||
local borderMap = { | local borderMap = { | ||
bd = "border", | bd = "border", | ||
| 113번째 줄: | 146번째 줄: | ||
ous = "outset", | ous = "outset", | ||
} | } | ||
local function addStyle(list, name, value) | |||
if not name or name == "" then return end | |||
if not value or value == "" then return end | |||
-- background-color, background, border-color 등을 포괄하도록 수정 | |||
local isBackground = name:match("background") ~= nil or name:match("border") ~= nil | |||
value = convertValue(value, isBackground) | |||
table.insert(list, name .. ":" .. value .. ";") | |||
end | end | ||
| 130번째 줄: | 166번째 줄: | ||
table.insert(result, borderTypeMap[part]) | table.insert(result, borderTypeMap[part]) | ||
else | else | ||
table.insert(result, convertValue(part)) | table.insert(result, convertValue(part, true)) | ||
end | end | ||
end | end | ||
| 182번째 줄: | 218번째 줄: | ||
return tokens | return tokens | ||
end | end | ||
local function parseSpec(spec) | local function parseSpec(spec) | ||
local styles = {} | |||
local colspan, rowspan | |||
for _, token in ipairs(tokenizeSpec(spec)) 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) | |||
if key == "px" then | |||
-- convertValue를 여기서 호출하지 않고 addStyle에 맡깁니다. | |||
addStyle(styles, "padding-left", val) | |||
addStyle(styles, "padding-right", val) | |||
elseif key == "py" then | |||
addStyle(styles, "padding-top", val) | |||
addStyle(styles, "padding-bottom", val) | |||
elseif key == "mx" then | |||
addStyle(styles, "margin-left", val) | |||
addStyle(styles, "margin-right", val) | |||
elseif key == "my" then | |||
addStyle(styles, "margin-top", val) | |||
addStyle(styles, "margin-bottom", val) | |||
elseif borderMap[key] then | |||
buildBorder(token, borderMap[key], styles) | |||
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 | end | ||
function p.attr(frame) | function p.attr(frame) | ||
local args = getArgs(frame) | local args = getArgs(frame) | ||
| 250번째 줄: | 273번째 줄: | ||
local css, cToken, rToken = parseSpec(spec) | local css, cToken, rToken = parseSpec(spec) | ||
local colspan = args.col or cToken | local colspan = args.col or cToken | ||
local rowspan = args.row or rToken | local rowspan = args.row or rToken | ||
| 269번째 줄: | 291번째 줄: | ||
end | end | ||
function p.css(frame) | function p.css(frame) | ||
local args = getArgs(frame) | local args = getArgs(frame) | ||
2026년 1월 2일 (금) 21:57 기준 최신판
이 모듈에 대한 설명문서는 모듈:Style/설명문서에서 만들 수 있습니다
local currentFrame
local HSL = require('Module:HSL')
local HSL2 = require('Module:HSL2')
local p = {}
function p.attr(frame)
currentFrame = frame
end
function p.css(frame)
currentFrame = frame
end
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
local function callHSL(moduleName, hex)
if not currentFrame then
return hex
end
local r, g, b = hexToRGB(hex)
return currentFrame:callParserFunction(
'#invoke',
moduleName,
'main',
'1=' .. hex, -- ⭐ 이게 핵심
'r=' .. r,
'g=' .. g,
'b=' .. b
)
end
local function convertValue(val, isBackground)
if not val then return val end
val = mw.text.trim(val)
-- <...> 벗기기
if mw.ustring.sub(val, 1, 1) == "<"
and mw.ustring.sub(val, -1) == ">" then
val = mw.text.trim(mw.ustring.sub(val, 2, -2))
end
-- CSS 변수
if mw.ustring.sub(val, 1, 1) == "$" then
return "var(--" .. mw.ustring.sub(val, 2) .. ")"
end
if mw.ustring.match(val, "^##[%x%X][%x%X][%x%X][%x%X][%x%X][%x%X]$") then
local hex = "#" .. mw.ustring.sub(val, 3)
if isBackground then
return "light-dark(" .. hex .. ", " .. HSL.main{ [1] = hex } .. ")"
else
return "light-dark(" .. hex .. ", " .. HSL2.main{ [1] = hex } .. ")"
end
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",
fd = "flex-direction",
ls = "letter-spacing",
ta = "text-align",
gap = "gap",
op = "opacity",
w = "width",
h = "height",
maxw = "max-width",
minw = "min-width",
fl = "float",
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",
va = "vertical-align",
bdrad = "border-radius",
wb = "word-break",
}
local borderMap = {
bd = "border",
bdt = "border-top",
bdr = "border-right",
bdb = "border-bottom",
bdl = "border-left",
bdw = "border-width",
}
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
-- background-color, background, border-color 등을 포괄하도록 수정
local isBackground = name:match("background") ~= nil or name:match("border") ~= nil
value = convertValue(value, isBackground)
table.insert(list, name .. ":" .. value .. ";")
end
local function buildBorder(token, cssName, styles)
local parts = mw.text.split(token, "-")
table.remove(parts, 1)
local result = {}
for _, part in ipairs(parts) do
if borderTypeMap[part] then
table.insert(result, borderTypeMap[part])
else
table.insert(result, convertValue(part, true))
end
end
addStyle(styles, cssName, table.concat(result, " "))
end
local function tokenizeSpec(spec)
local tokens = {}
local i = 1
local len = mw.ustring.len(spec)
while i <= len do
local ch = mw.ustring.sub(spec, i, i)
if ch == "<" then
local j = i + 1
while j <= len and mw.ustring.sub(spec, j, j) ~= ">" do
j = j + 1
end
table.insert(tokens, mw.ustring.sub(spec, i, j))
i = j + 1
elseif ch:match("%s") then
i = i + 1
else
local j = i
while j <= len do
local c = mw.ustring.sub(spec, j, j)
if c:match("%s") then
break
elseif c == "<" then
-- <...> 블록 통째로 포함
j = j + 1
while j <= len and mw.ustring.sub(spec, j, j) ~= ">" do
j = j + 1
end
j = j + 1
else
j = j + 1
end
end
table.insert(tokens, mw.ustring.sub(spec, i, j - 1))
i = j
end
end
return tokens
end
local function parseSpec(spec)
local styles = {}
local colspan, rowspan
for _, token in ipairs(tokenizeSpec(spec)) 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)
if key == "px" then
-- convertValue를 여기서 호출하지 않고 addStyle에 맡깁니다.
addStyle(styles, "padding-left", val)
addStyle(styles, "padding-right", val)
elseif key == "py" then
addStyle(styles, "padding-top", val)
addStyle(styles, "padding-bottom", val)
elseif key == "mx" then
addStyle(styles, "margin-left", val)
addStyle(styles, "margin-right", val)
elseif key == "my" then
addStyle(styles, "margin-top", val)
addStyle(styles, "margin-bottom", val)
elseif borderMap[key] then
buildBorder(token, borderMap[key], styles)
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
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)
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
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