Модуль:Loc/Marking: различия между версиями
Pok (обсуждение | вклад) мНет описания правки |
Pok (обсуждение | вклад) Нет описания правки |
||
| (не показаны 52 промежуточные версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
local p = {} | local p = {} | ||
local function apply_tag(tag, | local function apply_tag(tag, params, inner) | ||
local t = mw.ustring.lower(tag or "") | local t = mw.ustring.lower(tag or "") | ||
if t == "bold" then | if t == "bold" then | ||
| Строка 9: | Строка 9: | ||
elseif t == "bolditalic" then | elseif t == "bolditalic" then | ||
return "<i><b>" .. inner .. "</b></i>" | return "<i><b>" .. inner .. "</b></i>" | ||
elseif t == "bullet" then | |||
return "· " .. inner | |||
elseif t == "color" then | elseif t == "color" then | ||
local color = params and params._value or "" | |||
return '<span style="color:' .. color .. ';">' .. inner .. '</span>' | |||
elseif t == "head" then | |||
local level = params and tonumber(params._value) or 1 | |||
return '<h' .. level .. '>' .. inner .. '</h' .. level .. '>' | |||
elseif t == "font" then | |||
local family = params and params._value or nil | |||
local size = params and tonumber(params.size) or nil | |||
local style_parts = {} | |||
if family and family ~= "" then | |||
table.insert(style_parts, "font-family:" .. family) | |||
end | |||
if size and size ~= "" then | |||
table.insert(style_parts, "font-size:" .. size .. "px") | |||
end | |||
if #style_parts == 0 then | |||
return '<span>' .. inner .. '</span>' | return '<span>' .. inner .. '</span>' | ||
else | |||
return '<span style="' .. table.concat(style_parts, "; ") .. ';">' .. inner .. '</span>' | |||
end | end | ||
else | else | ||
return inner | return inner | ||
end | end | ||
end | |||
local function trim(s) | |||
if not s then return s end | |||
s = mw.ustring.gsub(s, "^%s+", "") | |||
s = mw.ustring.gsub(s, "%s+$", "") | |||
return s | |||
end | |||
local function parse_attrs(attr_str) | |||
if not attr_str then return nil end | |||
attr_str = mw.ustring.gsub(attr_str, "^%s*=%s*", "") | |||
attr_str = trim(attr_str) | |||
if attr_str == "" then return nil end | |||
local params = {} | |||
local function unquote_val(v) | |||
if not v then return v end | |||
v = trim(v) | |||
v = mw.ustring.gsub(v, "^"(.-)"$", "%1") | |||
v = mw.ustring.gsub(v, '^"(.-)"$', "%1") | |||
return v | |||
end | |||
for k, v in mw.ustring.gmatch(attr_str, "([%w_%-%:]+)%s*=%s*\"(.-)\"") do | |||
params[mw.ustring.lower(k)] = unquote_val(v) | |||
end | |||
attr_str = mw.ustring.gsub(attr_str, "([%w_%-%:]+)%s*=%s*\"(.-)\"", "") | |||
for k, v in mw.ustring.gmatch(attr_str, "([%w_%-%:]+)%s*=%s*([^%s%]]+)") do | |||
params[mw.ustring.lower(k)] = unquote_val(v) | |||
end | |||
attr_str = mw.ustring.gsub(attr_str, "([%w_%-%:]+)%s*=%s*([^%s%]]+)", "") | |||
local unnamed = mw.ustring.match(attr_str, "%s*"(.-)"") or mw.ustring.match(attr_str, "%s*\"(.-)\"") | |||
if unnamed then | |||
params._value = unquote_val(unnamed) | |||
attr_str = mw.ustring.gsub(attr_str, "%s*"(.-)"", "", 1) | |||
attr_str = mw.ustring.gsub(attr_str, "%s*\"(.-)\"", "", 1) | |||
end | |||
if not params._value then | |||
local v = mw.ustring.match(attr_str, "%s*([^%s%]]+)") | |||
if v then params._value = unquote_val(v) end | |||
end | |||
return params | |||
end | |||
local function convert_lists(s, indent_size) | |||
indent_size = indent_size or 2 | |||
if not s or s == "" then return s end | |||
local lines = mw.text.split(s, "\n") | |||
local out_lines = {} | |||
local stack = {} | |||
local function make_prefix_from_stack() | |||
if #stack == 0 then return "" end | |||
return table.concat(stack, "") | |||
end | |||
for _, line in ipairs(lines) do | |||
local line_unescaped = mw.ustring.gsub(line, " ", " ") | |||
local leading, num, rest_num = mw.ustring.match(line_unescaped, "^(%s*)(%d+)%.%s*(.*)$") | |||
local leading2, rest_dash = mw.ustring.match(line_unescaped, "^(%s*)%-%s+(.*)$") | |||
if num then | |||
local indent = mw.ustring.len(leading or "") | |||
local level = math.floor(indent / indent_size) | |||
while #stack > level do table.remove(stack) end | |||
if #stack == level then | |||
table.insert(stack, "#") | |||
else | |||
while #stack < level do table.insert(stack, "#") end | |||
table.insert(stack, "#") | |||
end | |||
local prefix = make_prefix_from_stack() | |||
local text = rest_num or "" | |||
table.insert(out_lines, (prefix ~= "" and (prefix .. (text ~= "" and (" " .. text) or "")) or text)) | |||
elseif rest_dash then | |||
local indent = mw.ustring.len(leading2 or "") | |||
local level = math.floor(indent / indent_size) | |||
while #stack > level do table.remove(stack) end | |||
if #stack == level then | |||
table.insert(stack, "*") | |||
else | |||
while #stack < level do table.insert(stack, "*") end | |||
table.insert(stack, "*") | |||
end | |||
local prefix = make_prefix_from_stack() | |||
local text = rest_dash or "" | |||
table.insert(out_lines, (prefix ~= "" and (prefix .. (text ~= "" and (" " .. text) or "")) or text)) | |||
else | |||
stack = {} | |||
table.insert(out_lines, line) | |||
end | |||
end | |||
return table.concat(out_lines, "\n") | |||
end | end | ||
local function transform(s) | local function transform(s) | ||
s = s or "" | s = s or "" | ||
s = mw.ustring.gsub(s, "%[tooltip([^%]]*)%]", function(raw_attrs) | |||
local params = parse_attrs(raw_attrs) | |||
local tip = "" | |||
local visible = "" | |||
if params then | |||
if params.tooltip then tip = params.tooltip end | |||
if params.text then visible = params.text end | |||
if visible == "" and params._value then visible = params._value end | |||
if tip == "" and params._value and visible ~= params._value then tip = params._value end | |||
end | |||
return "{{altTooltip|1=" .. (visible or "") .. "|2=<span style='white-space:pre-wrap;'>{{#invoke:Loc|GetRawString|noFormat=1|" .. (tip or "") .. "}}</span>}}" | |||
end) | |||
while true do | while true do | ||
local c_s, c_e, c_tag = mw.ustring.find(s, "%[/([%w_]+)%]") | local c_s, c_e, c_tag = mw.ustring.find(s, "%[/([%w_]+)%]") | ||
if not c_s then break end | if not c_s then break end | ||
local last_o_s, last_o_e = nil, nil | local last_o_s, last_o_e = nil, nil | ||
local search_pos = 1 | local search_pos = 1 | ||
while true do | while true do | ||
local a, b = mw.ustring.find(s, "%[" .. c_tag .. " | local a, b = mw.ustring.find(s, "%[" .. c_tag .. "[^%]]*%]", search_pos) | ||
if not a or a > c_s then break end | if not a or a > c_s then break end | ||
last_o_s, last_o_e = a, b | last_o_s, last_o_e = a, b | ||
search_pos = b + 1 | search_pos = b + 1 | ||
end | end | ||
if not last_o_s then | if not last_o_s then | ||
s = mw.ustring.sub(s, 1, c_s - 1) .. mw.ustring.sub(s, c_e + 1) | s = mw.ustring.sub(s, 1, c_s - 1) .. mw.ustring.sub(s, c_e + 1) | ||
else | else | ||
local inner = mw.ustring.sub(s, last_o_e + 1, c_s - 1) | local inner = mw.ustring.sub(s, last_o_e + 1, c_s - 1) | ||
local _, _, | local _, _, raw_attrs = mw.ustring.find(s, "%[" .. c_tag .. "([^%]]*)%]", last_o_s) | ||
local replacement = apply_tag(c_tag, | local params = parse_attrs(raw_attrs) | ||
local replacement = apply_tag(c_tag, params, inner) | |||
s = mw.ustring.sub(s, 1, last_o_s - 1) .. replacement .. mw.ustring.sub(s, c_e + 1) | s = mw.ustring.sub(s, 1, last_o_s - 1) .. replacement .. mw.ustring.sub(s, c_e + 1) | ||
end | end | ||
end | end | ||
s = mw.ustring.gsub(s, "%[/?[%w_]+[^%]]*%]", "") | s = mw.ustring.gsub(s, "%[/?[%w_]+[^%]]*%]", "") | ||
s = convert_lists(s) | |||
return s | |||
end | |||
return | local function process_nowiki_equals(str) | ||
str = str:gsub('#', '#') | |||
:gsub('=', '=') | |||
:gsub(' ', ' ') | |||
:gsub('{"', '') | |||
:gsub('"}', '') | |||
:gsub('{', '{') | |||
:gsub('"', '"') | |||
:gsub("'", ' ') | |||
:gsub('*', '*') | |||
return str | |||
end | end | ||
| Строка 60: | Строка 194: | ||
local args = frame.args or {} | local args = frame.args or {} | ||
local text = args[1] or args.text or "" | local text = args[1] or args.text or "" | ||
return frame:preprocess( | local noFormat = args.noFormat | ||
text = mw.text.unstripNoWiki(text) | |||
text = process_nowiki_equals(text) | |||
local class = noFormat and "ts-loc-format" or "" | |||
local content = transform(text) | |||
if mw.ustring.find(content, '^[ \t]*[#%*;%:]+') then | |||
content = '\n' .. content | |||
end | |||
return frame:preprocess( | |||
frame:extensionTag( | |||
'templatestyles', | |||
'', | |||
{ src = 'Модуль:Loc/styles.css' } | |||
) .. | |||
'<span class="list-reset-margin ' .. class .. '">' .. content .. '</span>' | |||
) | |||
end | end | ||
return p | return p | ||